Search Results

Search found 16413 results on 657 pages for 'array manipulation'.

Page 421/657 | < Previous Page | 417 418 419 420 421 422 423 424 425 426 427 428  | Next Page >

  • Rails Multiple Checkboxes with Javascript Dynamic Select

    - by Jack
    Hi, I have followed the Railscast episode 88 to implement a set of dependant drop down menus. In the students-new view, when the student's year is selected, the javascript figures out which courses are available to that year and offers the selection in a new drop down menu. My javascript erb file is here: var courses = new Array(); <% for course in @courses -%> <%for year in course.years -%> courses.push(new Array(<%= year.year_id%>, '<%=h course.title%>', <%= course.id%>)); <%end -%> <% end -%> function yearSelected() { year_id = $('student_year_id').getValue(); options = $('student_course_ids').options; options.length = 1; courses.each(function(course) { if (course[0] == year_id) { options[options.length] = new Option(course[1], course[2]); } }); if (options.length == 1) { $('course_field').hide(); } else { $('course_field').show(); } } document.observe('dom:loaded', function() { yearSelected(); $('student_year_id').observe('change', yearSelected); }); Any my view is as follows: <% form_for(@student) do |f| %> <%= f.error_messages %> <p> <%= f.label :name %><br /> <%= f.text_field :name %> </p> <p> <%= f.label :cid, "CID" %><br /> <%= f.text_field :cid %> </p> <p> <label for="student_year_id">Year:</label> <%= collection_select(:student, :year_id, Year.all, :id, :title, {:prompt => true})%> </p> <p id="course_field"> <label for="student_course_ids">Course:</label> <%= collection_select(:student, :course_ids, Course.find(:all), :id, :title, {:prompt => true}, {:multiple => true})%> </p> <p> <%= f.submit 'Save' %> </p> <% end %> What I would like to do is to add checkboxes instead of the drop down menu. Any suggestions? I previously was using this method, but was not able to get it to work with the new javascript. Cheers

    Read the article

  • PHP mysqli wrapper: passing by reference with __call() and call_user_func_array()

    - by Dave
    Hi everyone. I'm a long running fan of stackoverflow, first time poster. I'd love to see if someone can help me with this. Let me dig in with a little code, then I'll explain my problem. I have the following wrapper classes: class mysqli_wrapper { private static $mysqli_obj; function __construct() // Recycles the mysqli object { if (!isset(self::$mysqli_obj)) { self::$mysqli_obj = new mysqli(MYSQL_SERVER, MYSQL_USER, MYSQL_PASS, MYSQL_DBNAME); } } function __call($method, $args) { return call_user_func_array(array(self::$mysqli_obj, $method), $args); } function __get($para) { return self::$mysqli_obj->$para; } function prepare($query) // Overloaded, returns statement wrapper { return new mysqli_stmt_wrapper(self::$mysqli_obj, $query); } } class mysqli_stmt_wrapper { private $stmt_obj; function __construct($link, $query) { $this->stmt_obj = mysqli_prepare($link, $query); } function __call($method, $args) { return call_user_func_array(array($this->stmt_obj, $method), $args); } function __get($para) { return $this->stmt_obj->$para; } // Other methods will be added here } My problem is that when I call bind_result() on the mysqli_stmt_wrapper class, my variables don't seem to be passed by reference and nothing gets returned. To illustrate, if I run this section of code, I only get NULL's: $mysqli = new mysqli_wrapper; $stmt = $mysqli->prepare("SELECT cfg_key, cfg_value FROM config"); $stmt->execute(); $stmt->bind_result($cfg_key, $cfg_value); while ($stmt->fetch()) { var_dump($cfg_key); var_dump($cfg_value); } $stmt->close(); I also get a nice error from PHP which tells me: PHP Warning: Parameter 1 to mysqli_stmt::bind_result() expected to be a reference, value given in test.php on line 48 I've tried to overload the bind_param() function, but I can't figure out how to get a variable number of arguments by reference. func_get_args() doesn't seem to be able to help either. If I pass the variables by reference as in $stmt->bind_result(&$cfg_key, &$cfg_value) it should work, but this is deprecated behaviour and throws more errors. Does anyone have some ideas around this? Thanks so much for your time.

    Read the article

  • Comparing file contents in F#

    - by Bartosz Milewski
    I wrote a quick and dirty function to compare file contents (BTW, I have already tested that they are of equal size): let eqFiles f1 f2 = let bytes1 = Seq.ofArray (File.ReadAllBytes f1) let bytes2 = Seq.ofArray (File.ReadAllBytes f2) let res = Seq.compareWith (fun x y -> (int x) - (int y)) bytes1 bytes2 res = 0 I'm not happy with reading the whole contents into an array. I'd rather have a lazy sequence of bytes, but I can't find the right API in F#.

    Read the article

  • are deleted entries counted in the load factor of a hash table using open addressing

    - by Dr. Monkey
    When calculating the load factor of a hashtable with an open-addressing array implementation I am using: numberOfKeysInArray/sizeOfArray however it occurred to me that since deleted entries must be marked as such (to distinguish them from empty spaces), it might make sense to include these in the number of keys. My thinking is that as far as estimating the average number of probes to find an entry, deleted entries should count towards the load factor, but as far as inserting a new key they should not. Which is the proper calculation: including deleted keys or not?

    Read the article

  • Can't create file in Ada 95

    - by duder
    Hello, I'm trying to follow a standard reference for opening files but running into a constraint_error at the line when I call Ada.Text_IO.Create(). It says "range check failed". Any help appreciated, here's the code: WITH Ada.Text_IO; WITH Ada.Integer_Text_IO; USE Ada.Text_IO; USE Ada.Integer_Text_IO; PROCEDURE FileManip IS --Variables Start_Int : Integer; Stop_Int : Integer; Max_Length : Integer; --Output File MaxName : CONSTANT Positive := 80; SUBTYPE NameRange IS Positive RANGE 1..MaxName; OutFileName : String(NameRange) := (OTHERS => '#'); OutNameLength : NameRange; OutData : File_Type; --Array TYPE Chain_Array IS ARRAY(1..500) OF Integer; Sum : Integer := 1; BEGIN --Inputs Ada.Text_IO.Put(Item => "Enter a starting Integer: "); Ada.Integer_Text_IO.Get(Item => Start_Int); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Enter a stopping Integer: "); Ada.Integer_Text_IO.Get(Item => Stop_Int); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Enter a Maximum Length to search: "); Ada.Integer_Text_IO.Get(Item => Max_Length); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Enter a output file name > "); Ada.Text_IO.Get_Line( Item => OutFileName, Last => OutNameLength); Ada.Text_IO.Create( File => OutData, Mode => Ada.Text_IO.Out_File, Name => OutFileName(1..OutNameLength)); Ada.Text_IO.New_Line;

    Read the article

  • How to receive XMLHttpRequest with PHP?

    - by Adrian
    I would like to be able to read XMLHttpRequest that is sent to a PHP page. I am using prototype's Ajax.Request function, and I am sending a simple XML structure. When trying to print the POST array on the PHP page, I don't get any output. Any help appreciated.

    Read the article

  • Javascript callback and google maps api question

    - by es11
    I am using google maps api v3 and have an array of arrays object: MVCArray.<MVCArray.<LatLng>> I want to iterate over this. I see that MVCArray has a method forEach which uses a call back, but I have no idea how to use this (I haven't done much js). The api defines this method as follows: forEach(callback:function(*, number))) Could somebody please show me an example of how to use this given an MVCArray of MVCArrays?

    Read the article

  • How to load a binary file(.bin) of size 6 MB in a varbinary(MAX) column of SQL Server 2005 database

    - by Feroz Khan
    How to load a binary file(.bin) of size 6 MB in a varbinary(MAX) column of SQL Server 2005 database using ADO in vc++ application. This is the code I am using to load the file which I used to load a .bmp file BOOL CSaveView::PutECGInDB(CString strFilePath, FieldPtr pFileData) { //Open File CFile fileImage; CFileStatus fileStatus; fileImage.Open(strFilePath,CFile::modeRead); fileImage.GetStatus(fileStatus); //Alocating memory for data ULONG nBytes = (ULONG)fileStatus.m_size; HGLOBAL hGlobal = GlobalAlloc(GPTR,nBytes); LPVOID lpData = GlobalLock(hGlobal); //Putting data into file fileImage.Read(lpData,nBytes); HRESULT hr; _variant_t varChunk; long lngOffset = 0; UCHAR chData; SAFEARRAY FAR *psa = NULL; SAFEARRAYBOUND rgsabound[1]; try { //Create a safe array to store the BYTES rgsabound[0].lLbound = 0; rgsabound[0].cElements = nBytes; psa = SafeArrayCreate(VT_UI1,1,rgsabound); while(lngOffset<(long)nBytes) { chData = ((UCHAR*)lpData)[lngOffset]; hr = SafeArrayPutElement(psa,&lngOffset,&chData); if(hr != S_OK) { return false; } lngOffset++; } lngOffset = 0; //Assign the safe array to a varient varChunk.vt = VT_ARRAY|VT_UI1; varChunk.parray = psa; hr = pFileData-AppendChunk(varChunk); if(hr != S_OK) { return false; } } catch(_com_error &e) { //get info from _com_error _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); _bstr_t bstrErrorMessage(e.ErrorMessage()); _bstr_t bstrErrorCode(e.Error()); TRACE("Exception thrown for classes generated by #import"); TRACE("\tCode= %08lx\n",(LPCSTR)bstrErrorCode); TRACE("\tCode Meaning = %s\n",(LPCSTR)bstrErrorMessage); TRACE("\tSource = %s\n",(LPCSTR)bstrSource); TRACE("\tDescription = %s\n",(LPCSTR)bstrDescription); } catch(...) { TRACE("Unhandle Exception"); } //Free Memory GlobalUnlock(lpData); return true; } But when I read the same file using Getchunk funcion it gives me all 0,s but the size of the file I get is same as the one uploaded. Your help will be highly appreciated. Thanks in advance.

    Read the article

  • How come nobody wrote RadioMenuItems class for Winforms?

    - by Pavel Radzivilovsky
    Or maybe google is just not so friendly to me? What I want is this simple thing: constructor that accepts an array of menu item objects Value get/set property that would set all the Checked properties right bind to all Clicked events of the supplied items and provide One event Working DataBind facilities If you encountered such a nice thing around, please direct me. No need for manual do-it-in-your-form1.cs-class links, please. This I can do myself.

    Read the article

  • bug/error in basis set path algorithm i can't figure out

    - by Roy McAvoy
    The following looks through a 2d array to find basis set paths. It is supposed to print out the individual paths but not repeat any and end when all paths are found. It however doesn't stop at the last path and has a bug in it somewhere in which the following happens: It goes halfway through the path and then goes to zero and ends the path for some reason. For example the table is filled with the following: all 0s, except for [1][2], [1][3], [2][4], [2][5], [3][5], [4][6], [5][6], [6][0] which all have a 1 in them. The desired paths are P1: 1 2 4 6 0 P2: 1 3 5 6 0 P3: 1 2 5 6 0. The output I get when i run the program is 12460 13560 1250 124 Any and all help on this is much appreciated, this is just the function that scans through the array looking for paths, I can add the entire program if that would be helpful. Thanks.. void find_path(int map[][MAX], int x){ int path =0; int m=1; int blah=0; bool path_found = false; do { for(int n=0;n<(x+1);n++){ if(map[m][n]==-1){ blah=(n+1); if(blah<(x+1)){ for(blah;blah<(x+1);blah++){ if(map[m][blah]==1){ map[m][blah]=-1; path=m; path_found = true; cout<<path; m=blah; n=0; } } } else{ path=m; path_found=false; cout<<path; m=n; if(m==0){ path=0; cout<<path<<endl; m=1; path_found=false; } } } else if(map[m][n]==1){ map[m][n]=-1; path=m; path_found = true; cout<<path; m=n; if(m==0){ path=0; cout<<path<<endl; m=1; path_found=false; } } } } while(m<(x+1) && path_found); }

    Read the article

  • Jquery Ajax Call In For Loop Only Runs Once - Possible Issue with Timing & Exit Condition?

    - by Grumps
    Background I'm building a form that uses autocomplete against the EchoNest API. First the users picks an artist, using the Artist Suggest call. Next they select a song but the Song and/Or Artist song search doesn't provide a "wild card" search. It only returns exact matches. So based on the forums they suggest building an array of the songs and using auto complete on the array. I can only get a maximum of 100 responses at a time. I do know based on the initial response the number of songs. My Plan: Wrap the ajax call in a for loop ('runonceloop'). Amend the loop exit condition after the first response with the total number of songs. Challenge I'm having: The 'runonceloop' only completes a singe loop because or at least that's what I believe: The exit condition is satisfied before the first response [1] is received. I've tried to adjust the 'exit condition' and 'counter' such that they are set and and increased at the end of the success block. This seems to lock up my browser. Can someone provide some guidance on this situation?[2] I'd really appreciate it. I also don't think turning async off is a good idea because it locks the browser. Response[1]: { "response": { "status": { "code": "0", "message": "Success", "version": "4.2" }, "start": 0, "total": 121, //Used for "songs": [ { "id": "SOXZYYG127F3E1B7A2", "title": "Karma police" }, { "id": "SOXZABD127F3E1B7A2", "title" : "Creep" } ] } } } Code[2] var songsList = []; function getSongs() { var numsongs = 2; //at least 2 runs. var startindex = 0; runonceloop: //<~~~~Referenced in question for (var j = 0;j >= numsongs;) { console.log('numsongs' + numsongs); $.ajax({ url: "http://developer.echonest.com/api/v4/artist/songs", dataType: "jsonp", data: { results: 100, api_key: "XXXXXXXXXXX", format: "jsonp", name: $("#artist").val(), start: startindex }, success: function (data) { var songs = data.response.songs; numsongs = data.response.total; //modify exit condition for (var i = 0; i < songs.length; i++) { songsList.push(songs[i].title); } j +=100;// increase by 100 to match number of responses. } }); }};

    Read the article

  • Apple Push Notifications With Foreign Accent Characters Not Receiving

    - by confeng
    I'm sending push notifications and when the message contains foreign characters (Turkish in my case) like I, s, ç, g... The message does not arrive to devices. Here's my code: $message = 'THIS is push'; $passphrase = 'mypass'; $ctx = stream_context_create(); stream_context_set_option($ctx, 'ssl', 'local_cert', 'MyPemFile.pem'); stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); // Open a connection to the APNS server $fp = stream_socket_client( 'ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); if (!$fp) exit("Failed to connect: $err $errstr" . PHP_EOL); echo 'Connected to Apple service. ' . PHP_EOL; // Encode the payload as JSON $body['aps'] = array( 'alert' => $message, 'sound' => 'default' ); $payload = json_encode($body); $result = 'Start'.PHP_EOL; $tokenArray = array('mytoken'); foreach ($tokenArray as $item) { // Build the binary notification $msg = chr(0) . pack('n', 32) . pack('H*', $item) . pack('n', strlen($payload)) . $payload; // Send it to the server $result = fwrite($fp, $msg, strlen($msg)); if (!$result) echo 'Failed message'.PHP_EOL; else echo 'Successful message'.PHP_EOL; } // Close the connection to the server fclose($fp); I have tried encoding $message variable with utf8_encode() but the message received as "THÝS is push". And other ways like iconv() didn't work for me, some of them cropped Turkish characters, some didn't receive at all. I also have header('content-type: text/html; charset: utf-8'); and <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> in my page. I don't think the problem appears while I set the value but maybe with pack() function. Any ideas to solve this without replacing characters with English?

    Read the article

  • iPhone: Speeding up a search that's polling 17,000 Core Data objects

    - by randombits
    I have a class that conforms to UISearchDisplayDelegate and contains a UISearchBar. This view is responsible for allowing the user to poll a store of about 17,000 objects that are currently managed by Core Data. Everytime the user types in a character, I created an instance of a SearchOperation (subclasses NSOperation) that queries Core Data to find results that might match the search. The code in the search controller looks something like: - (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope { // Update the filtered array based on the search text and scope in a secondary thread if ([searchText length] < 3) { [filteredList removeAllObjects]; // First clear the filtered array. [self setFilteredList:NULL]; [self.tableView reloadData]; return; } NSDictionary *searchdict = [NSDictionary dictionaryWithObjectsAndKeys:scope, @"scope", searchText, @"searchText", nil]; [aSearchQueue cancelAllOperations]; SearchOperation *searchOp = [[SearchOperation alloc] initWithDelegate:self dataDict:searchdict]; [aSearchQueue addOperation:searchOp]; } And my search is rather straight forward. SearchOperation is a subclass of NSOperation. I overwrote the main method with the following code: - (void)main { if ([self isCancelled]) { return; } NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; [fetchRequest setEntity:entity]; NSPredicate *predicate = NULL; predicate = [NSPredicate predicateWithFormat:@"(someattr contains[cd] %@)", searchText]; [fetchRequest setPredicate:predicate]; NSError *error = NULL; NSArray *fetchResults = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; [fetchRequest release]; if (self.delegate != nil) [self.delegate didFinishSearching:fetchResults]; [pool drain]; } This code works, but it has several issues. It's slow. Even though I have the search happening in a separate thread other than the UI thread, querying 17,000 objects is clearly not optimal. If I'm not careful, crashes can happen. I set the max concurrent searches in my NSOperationQueue to 1 to avoid this. What else can I do to make this search faster? I think preloading all 17,000 objects into memory might be risky. There has to be a smarter way to conduct this search to give results back to the user faster.

    Read the article

  • plot markers on google maps with json and jquery

    - by mark
    I am trying to plot the markers as defined in a json file om Google Maps but they don't show on the map. Can somebody help me with this problem? This is the Json file: http://sionvalais.com/gmap/markers/ This is the Javascritp function: function loadMarkers() { var bounds = map.getBounds(); var zoomLevel = map.getZoom(); $.post("/gmaps/markers/index.php", {zoom: zoomLevel, swLat: bounds.getSouthWest().lat(), swLon: bounds.getSouthWest().lng(), neLat: bounds.getNorthEast().lat(), neLon: bounds.getNorthEast().lng()}, function(data) { processMarkers(data, _smallMarkerSize); }, "json" ); } function processMarkers(webcams, markerSize) { var marker = null; var markersInView = new Array(); var idsInView = new Array(); // Loop through the new webcams for (var i = 0; i < webcams.length; i++) { var idx = markers.indexOf(webcams[i].id); if (idx == -1) { var info_html = "<table class='infowindow'>"; info_html += "<tr><td class='img'>"; info_html += "<img src='" + webcams[i].smallimg + "' /><td>"; info_html += "<td><p><b>" + webcams[i].loc + "</b>"; info_html += "<br /><a href='/webcam/" + webcams[i].url + "' target='_blank'>Show webcam</a></p></td></tr>"; info_html += "</table>"; marker = new WebcamMarker(new GLatLng(webcams[i].latitude, webcams[i].longitude), {image: "" + webcams[i].smallimg + "", height: markerSize, width: markerSize}); marker.myhtml = info_html; map.addOverlay(marker); markersInView[webcams[i].id] = marker; } else { markersInView[webcams[i].id] = markers[webcams[i].id]; } idsInView.push(webcams[i].id); } // Now remove the markers outside of the viewport for (var i = 0; i < webcamids.length; i++) { var idx = markersInView.indexOf(webcamids[i]); if (idx == -1) { marker = markers[webcamids[i]]; map.removeOverlay(marker); } } markers = markersInView; webcamids = idsInView; }

    Read the article

  • Do WordPress widget (or sidebar) hooks exist?

    - by Jeff
    I'm trying to filter ALL widget output through a simple filter, but can't find any hooks and was hoping to be pointed in the right direction. Or possibly my efforts are not even possible? My simple filter is something like this: function clean_widget_output( $input ) { return str_replace( array( "\t", "\n", "\r" ), '', $input ); } add_[FILTER OR ACTION]( 'need_a_hook', 'clean_widget_output', 99 ); Any ideas? I'm pretty new to PHP, but I can get around.

    Read the article

  • Doctrine DQL execute passing params

    - by Karim web Developer
    I used this DQL in Doctrine $q->update('product') ->set('quantity','?') ->where('id=?'); $q->execute(array(20,5)); I check the server for the query and this the generated sql UPDATE product SET quantity = '20', updated_at = '5' WHERE (id = '2010-04-26 14:34); So I need to know why the arguments aren't in the correct places?

    Read the article

  • Strange declaration(templates). C++

    - by atch
    Hi, guys could anyone explain to my like to a not very inteligent child what is declared here: (this is taken from another post on this forum) template<typename C> static char (&f(ChT<int Fallback::*, &C::x>*))[1]; how I read it is: template of static function f called with (ChT*) but then I can't make sense why is there address of operator and why is there array? When explaining please picture not very inteligent child and then try to make it clear to it. Thanks for any help

    Read the article

  • How to embed html table into the bpdy of email

    - by Michael Mao
    Hi all: I am sending info to target email via PHP native mail() method right now. Everything else works fine but the table part troubles me the most. See sample output : Dear Michael Mao : Thank you for purchasing flight tickets with us, here is your receipt : Your tickets will be delivered by mail to the following address : Street Address 1 : sdfsdafsadf sdf Street Address 2 : N/A City : Sydney State : nsw Postcode : 2 Country : Australia Credit Card Number : *************1234 Your purchase details are recorded as : <table><tr><th class="delete">del?</th><th class="from_city">from</th><th class="to_city">to</th><th class="quantity">qty</th><th class="price">unit price</th><th class="price">total price</th></tr><tr class="evenrow" id="Sydney-Lima"><td><input name="isDeleting" type="checkbox"></td><td>Sydney</td><td>Lima</td><td>1</td><td>1030.00</td><td>1030</td></tr><tr class="oddrow" id="Sydney-Perth"><td><input name="isDeleting" type="checkbox"></td><td>Sydney</td><td>Perth</td><td>3</td><td>340.00</td><td>1020</td></tr><tr class="totalprice"><td colspan="5">Grand Total Price</td><td id="grandtotal">2050</td></tr></table> The source of table is directly taken from a webpage, exactly as the same. However, Gmail, Hotmail and most of other emails will ignore to render this as a table. So I am wondering, without using Outlook or other email sending agent software, how could I craft a embedded table for the PHP mail() method to send? Current code snippet corresponds to table generation : $purchaseinfo = $_POST["purchaseinfo"]; //if html tags are not to be filtered in the body of email $stringBuilder .= "<table>" .stripslashes($purchaseinfo) ."</table>"; //must send json response back to caller ajax request if(mail($email, 'Your purchase information on www.hardlyworldtravel.com', $emailbody, $headers)) echo json_encode(array("feedback"=>"successful")); else echo json_encode(array("feedback"=>"error")); Any hints and suggestions are welcomed, thanks a lot in advance.

    Read the article

  • Steganography Experiment - Trouble hiding message bits in DCT coefficients

    - by JohnHankinson
    I have an application requiring me to be able to embed loss-less data into an image. As such I've been experimenting with steganography, specifically via modification of DCT coefficients as the method I select, apart from being loss-less must also be relatively resilient against format conversion, scaling/DSP etc. From the research I've done thus far this method seems to be the best candidate. I've seen a number of papers on the subject which all seem to neglect specific details (some neglect to mention modification of 0 coefficients, or modification of AC coefficient etc). After combining the findings and making a few modifications of my own which include: 1) Using a more quantized version of the DCT matrix to ensure we only modify coefficients that would still be present should the image be JPEG'ed further or processed (I'm using this in place of simply following a zig-zag pattern). 2) I'm modifying bit 4 instead of the LSB and then based on what the original bit value was adjusting the lower bits to minimize the difference. 3) I'm only modifying the blue channel as it should be the least visible. This process must modify the actual image and not the DCT values stored in file (like jsteg) as there is no guarantee the file will be a JPEG, it may also be opened and re-saved at a later stage in a different format. For added robustness I've included the message multiple times and use the bits that occur most often, I had considered using a QR code as the message data or simply applying the reed-solomon error correction, but for this simple application and given that the "message" in question is usually going to be between 10-32 bytes I have plenty of room to repeat it which should provide sufficient redundancy to recover the true bits. No matter what I do I don't seem to be able to recover the bits at the decode stage. I've tried including / excluding various checks (even if it degrades image quality for the time being). I've tried using fixed point vs. double arithmetic, moving the bit to encode, I suspect that the message bits are being lost during the IDCT back to image. Any thoughts or suggestions on how to get this working would be hugely appreciated. (PS I am aware that the actual DCT/IDCT could be optimized from it's naive On4 operation using row column algorithm, or an FDCT like AAN, but for now it just needs to work :) ) Reference Papers: http://www.lokminglui.com/dct.pdf http://arxiv.org/ftp/arxiv/papers/1006/1006.1186.pdf Code for the Encode/Decode process in C# below: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing.Imaging; using System.Drawing; namespace ImageKey { public class Encoder { public const int HIDE_BIT_POS = 3; // use bit position 4 (1 << 3). public const int HIDE_COUNT = 16; // Number of times to repeat the message to avoid error. // JPEG Standard Quantization Matrix. // (to get higher quality multiply by (100-quality)/50 .. // for lower than 50 multiply by 50/quality. Then round to integers and clip to ensure only positive integers. public static double[] Q = {16,11,10,16,24,40,51,61, 12,12,14,19,26,58,60,55, 14,13,16,24,40,57,69,56, 14,17,22,29,51,87,80,62, 18,22,37,56,68,109,103,77, 24,35,55,64,81,104,113,92, 49,64,78,87,103,121,120,101, 72,92,95,98,112,100,103,99}; // Maximum qauality quantization matrix (if all 1's doesn't modify coefficients at all). public static double[] Q2 = {1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1}; public static Bitmap Encode(Bitmap b, string key) { Bitmap response = new Bitmap(b.Width, b.Height, PixelFormat.Format32bppArgb); uint imgWidth = ((uint)b.Width) & ~((uint)7); // Maximum usable X resolution (divisible by 8). uint imgHeight = ((uint)b.Height) & ~((uint)7); // Maximum usable Y resolution (divisible by 8). // Start be transferring the unmodified image portions. // As we'll be using slightly less width/height for the encoding process we'll need the edges to be populated. for (int y = 0; y < b.Height; y++) for (int x = 0; x < b.Width; x++) { if( (x >= imgWidth && x < b.Width) || (y>=imgHeight && y < b.Height)) response.SetPixel(x, y, b.GetPixel(x, y)); } // Setup the counters and byte data for the message to encode. StringBuilder sb = new StringBuilder(); for(int i=0;i<HIDE_COUNT;i++) sb.Append(key); byte[] codeBytes = System.Text.Encoding.ASCII.GetBytes(sb.ToString()); int bitofs = 0; // Current bit position we've encoded too. int totalBits = (codeBytes.Length * 8); // Total number of bits to encode. for (int y = 0; y < imgHeight; y += 8) { for (int x = 0; x < imgWidth; x += 8) { int[] redData = GetRedChannelData(b, x, y); int[] greenData = GetGreenChannelData(b, x, y); int[] blueData = GetBlueChannelData(b, x, y); int[] newRedData; int[] newGreenData; int[] newBlueData; if (bitofs < totalBits) { double[] redDCT = DCT(ref redData); double[] greenDCT = DCT(ref greenData); double[] blueDCT = DCT(ref blueData); int[] redDCTI = Quantize(ref redDCT, ref Q2); int[] greenDCTI = Quantize(ref greenDCT, ref Q2); int[] blueDCTI = Quantize(ref blueDCT, ref Q2); int[] blueDCTC = Quantize(ref blueDCT, ref Q); HideBits(ref blueDCTI, ref blueDCTC, ref bitofs, ref totalBits, ref codeBytes); double[] redDCT2 = DeQuantize(ref redDCTI, ref Q2); double[] greenDCT2 = DeQuantize(ref greenDCTI, ref Q2); double[] blueDCT2 = DeQuantize(ref blueDCTI, ref Q2); newRedData = IDCT(ref redDCT2); newGreenData = IDCT(ref greenDCT2); newBlueData = IDCT(ref blueDCT2); } else { newRedData = redData; newGreenData = greenData; newBlueData = blueData; } MapToRGBRange(ref newRedData); MapToRGBRange(ref newGreenData); MapToRGBRange(ref newBlueData); for(int dy=0;dy<8;dy++) { for(int dx=0;dx<8;dx++) { int col = (0xff<<24) + (newRedData[dx+(dy*8)]<<16) + (newGreenData[dx+(dy*8)]<<8) + (newBlueData[dx+(dy*8)]); response.SetPixel(x+dx,y+dy,Color.FromArgb(col)); } } } } if (bitofs < totalBits) throw new Exception("Failed to encode data - insufficient cover image coefficients"); return (response); } public static void HideBits(ref int[] DCTMatrix, ref int[] CMatrix, ref int bitofs, ref int totalBits, ref byte[] codeBytes) { int tempValue = 0; for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { if ( (u != 0 || v != 0) && CMatrix[v+(u*8)] != 0 && DCTMatrix[v+(u*8)] != 0) { if (bitofs < totalBits) { tempValue = DCTMatrix[v + (u * 8)]; int bytePos = (bitofs) >> 3; int bitPos = (bitofs) % 8; byte mask = (byte)(1 << bitPos); byte value = (byte)((codeBytes[bytePos] & mask) >> bitPos); // 0 or 1. if (value == 0) { int a = DCTMatrix[v + (u * 8)] & (1 << HIDE_BIT_POS); if (a != 0) DCTMatrix[v + (u * 8)] |= (1 << HIDE_BIT_POS) - 1; DCTMatrix[v + (u * 8)] &= ~(1 << HIDE_BIT_POS); } else if (value == 1) { int a = DCTMatrix[v + (u * 8)] & (1 << HIDE_BIT_POS); if (a == 0) DCTMatrix[v + (u * 8)] &= ~((1 << HIDE_BIT_POS) - 1); DCTMatrix[v + (u * 8)] |= (1 << HIDE_BIT_POS); } if (DCTMatrix[v + (u * 8)] != 0) bitofs++; else DCTMatrix[v + (u * 8)] = tempValue; } } } } } public static void MapToRGBRange(ref int[] data) { for(int i=0;i<data.Length;i++) { data[i] += 128; if(data[i] < 0) data[i] = 0; else if(data[i] > 255) data[i] = 255; } } public static int[] GetRedChannelData(Bitmap b, int sx, int sy) { int[] data = new int[8 * 8]; for (int y = sy; y < (sy + 8); y++) { for (int x = sx; x < (sx + 8); x++) { uint col = (uint)b.GetPixel(x,y).ToArgb(); data[(x - sx) + ((y - sy) * 8)] = (int)((col >> 16) & 0xff) - 128; } } return (data); } public static int[] GetGreenChannelData(Bitmap b, int sx, int sy) { int[] data = new int[8 * 8]; for (int y = sy; y < (sy + 8); y++) { for (int x = sx; x < (sx + 8); x++) { uint col = (uint)b.GetPixel(x, y).ToArgb(); data[(x - sx) + ((y - sy) * 8)] = (int)((col >> 8) & 0xff) - 128; } } return (data); } public static int[] GetBlueChannelData(Bitmap b, int sx, int sy) { int[] data = new int[8 * 8]; for (int y = sy; y < (sy + 8); y++) { for (int x = sx; x < (sx + 8); x++) { uint col = (uint)b.GetPixel(x, y).ToArgb(); data[(x - sx) + ((y - sy) * 8)] = (int)((col >> 0) & 0xff) - 128; } } return (data); } public static int[] Quantize(ref double[] DCTMatrix, ref double[] Q) { int[] DCTMatrixOut = new int[8*8]; for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { DCTMatrixOut[v + (u * 8)] = (int)Math.Round(DCTMatrix[v + (u * 8)] / Q[v + (u * 8)]); } } return(DCTMatrixOut); } public static double[] DeQuantize(ref int[] DCTMatrix, ref double[] Q) { double[] DCTMatrixOut = new double[8*8]; for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { DCTMatrixOut[v + (u * 8)] = (double)DCTMatrix[v + (u * 8)] * Q[v + (u * 8)]; } } return(DCTMatrixOut); } public static double[] DCT(ref int[] data) { double[] DCTMatrix = new double[8 * 8]; for (int v = 0; v < 8; v++) { for (int u = 0; u < 8; u++) { double cu = 1; if (u == 0) cu = (1.0 / Math.Sqrt(2.0)); double cv = 1; if (v == 0) cv = (1.0 / Math.Sqrt(2.0)); double sum = 0.0; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { double s = data[x + (y * 8)]; double dctVal = Math.Cos((2 * y + 1) * v * Math.PI / 16) * Math.Cos((2 * x + 1) * u * Math.PI / 16); sum += s * dctVal; } } DCTMatrix[u + (v * 8)] = (0.25 * cu * cv * sum); } } return (DCTMatrix); } public static int[] IDCT(ref double[] DCTMatrix) { int[] Matrix = new int[8 * 8]; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { double sum = 0; for (int v = 0; v < 8; v++) { for (int u = 0; u < 8; u++) { double cu = 1; if (u == 0) cu = (1.0 / Math.Sqrt(2.0)); double cv = 1; if (v == 0) cv = (1.0 / Math.Sqrt(2.0)); double idctVal = (cu * cv) / 4.0 * Math.Cos((2 * y + 1) * v * Math.PI / 16) * Math.Cos((2 * x + 1) * u * Math.PI / 16); sum += (DCTMatrix[u + (v * 8)] * idctVal); } } Matrix[x + (y * 8)] = (int)Math.Round(sum); } } return (Matrix); } } public class Decoder { public static string Decode(Bitmap b, int expectedLength) { expectedLength *= Encoder.HIDE_COUNT; uint imgWidth = ((uint)b.Width) & ~((uint)7); // Maximum usable X resolution (divisible by 8). uint imgHeight = ((uint)b.Height) & ~((uint)7); // Maximum usable Y resolution (divisible by 8). // Setup the counters and byte data for the message to decode. byte[] codeBytes = new byte[expectedLength]; byte[] outBytes = new byte[expectedLength / Encoder.HIDE_COUNT]; int bitofs = 0; // Current bit position we've decoded too. int totalBits = (codeBytes.Length * 8); // Total number of bits to decode. for (int y = 0; y < imgHeight; y += 8) { for (int x = 0; x < imgWidth; x += 8) { int[] blueData = ImageKey.Encoder.GetBlueChannelData(b, x, y); double[] blueDCT = ImageKey.Encoder.DCT(ref blueData); int[] blueDCTI = ImageKey.Encoder.Quantize(ref blueDCT, ref Encoder.Q2); int[] blueDCTC = ImageKey.Encoder.Quantize(ref blueDCT, ref Encoder.Q); if (bitofs < totalBits) GetBits(ref blueDCTI, ref blueDCTC, ref bitofs, ref totalBits, ref codeBytes); } } bitofs = 0; for (int i = 0; i < (expectedLength / Encoder.HIDE_COUNT) * 8; i++) { int bytePos = (bitofs) >> 3; int bitPos = (bitofs) % 8; byte mask = (byte)(1 << bitPos); List<int> values = new List<int>(); int zeroCount = 0; int oneCount = 0; for (int j = 0; j < Encoder.HIDE_COUNT; j++) { int val = (codeBytes[bytePos + ((expectedLength / Encoder.HIDE_COUNT) * j)] & mask) >> bitPos; values.Add(val); if (val == 0) zeroCount++; else oneCount++; } if (oneCount >= zeroCount) outBytes[bytePos] |= mask; bitofs++; values.Clear(); } return (System.Text.Encoding.ASCII.GetString(outBytes)); } public static void GetBits(ref int[] DCTMatrix, ref int[] CMatrix, ref int bitofs, ref int totalBits, ref byte[] codeBytes) { for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { if ((u != 0 || v != 0) && CMatrix[v + (u * 8)] != 0 && DCTMatrix[v + (u * 8)] != 0) { if (bitofs < totalBits) { int bytePos = (bitofs) >> 3; int bitPos = (bitofs) % 8; byte mask = (byte)(1 << bitPos); int value = DCTMatrix[v + (u * 8)] & (1 << Encoder.HIDE_BIT_POS); if (value != 0) codeBytes[bytePos] |= mask; bitofs++; } } } } } } } UPDATE: By switching to using a QR Code as the source message and swapping a pair of coefficients in each block instead of bit manipulation I've been able to get the message to survive the transform. However to get the message to come through without corruption I have to adjust both coefficients as well as swap them. For example swapping (3,4) and (4,3) in the DCT matrix and then respectively adding 8 and subtracting 8 as an arbitrary constant seems to work. This survives a re-JPEG'ing of 96 but any form of scaling/cropping destroys the message again. I was hoping that by operating on mid to low frequency values that the message would be preserved even under some light image manipulation.

    Read the article

< Previous Page | 417 418 419 420 421 422 423 424 425 426 427 428  | Next Page >