• ### Announcements

#### Archived

This topic is now archived and is closed to further replies.

# Help? Anyone?

## Recommended Posts

This is one of the "I am new and my code takes six years to run; I also like jelly"-type posts, but I really need help. The code shown below is a *very* simple method of compacting animations (a bit like RLE). It was designed more as a test than anything else, but it would certainly help alot if I could increase the speed.
  bool MASICi9::CreateDGR(String file,short frames,String output,bool prepend) { ofstream loge("DGREncode.txt") // log file if (prepend){TBuffA->LoadFromFile(file + "0000.bmp");} else{TBuffA->LoadFromFile(file + "0.bmp");} //Load the source bitmap into a Graphics::TBitmap object. i2 = TBuffA->Height; i1 = TBuffA->Width; h = i1*i2; w = h*frames; loge << "DGR Encoder (1.6) -- MASICi9" << endl << "Writing DGR V.2 (adv)" << endl << "Pixels per image = " << h << endl << "Total number of pixels = " << w << endl; x = h; output += ".dgr"; //add extention to name of output file ofstream out(output.c_str(),ios::binary); //open an output file stream loge << "Writing header...."; out.put(''D''); //signature and version out.put(''G''); out.put(''R''); out.put(''2''); out.write((char *)(&frames),2); //frames out.write((char *)(&i1),4); //width out.write((char *)(&i2),4); //height loge << "done: " << frames << " frames, " << i1 << " width " << i2 << " height." << endl << "Writing first frame...."; h = 0; for (int bc = 0; bcCanvas->Pixels[ac][bc]; //store the 32 bit pixel data from the bitmap canvas in a TColor object. out.write((char *)(&T),sizeof(T)); //write the TColor object to the file h++; //log data } } w = 4*h; loge << "done: " << w << " bytes, forming " << h << " pixels." << endl; s = 9+w; for (int i = 1; i<=frames; i++) //for frames 2->n { loge << "Writing frame " << i+1 << "....."; //read the source frame, and the previous frame (TBuffA is the previous, TBuffG is the current frame). if (prepend) { if (i < 10) { TBuffA->LoadFromFile(file+ "000" + String(i-1)+".bmp"); TBuffG->LoadFromFile(file+ "000" + String(i)+".bmp"); } else if (i < 100) { if (i == 10){TBuffA->LoadFromFile(file+ "000" + String(i-1)+".bmp");} else {TBuffA->LoadFromFile(file+ "00" + String(i-1)+".bmp");} TBuffG->LoadFromFile(file+ "00" + String(i)+".bmp"); } else if (i < 1000) { if (i == 100){TBuffA->LoadFromFile(file+ "00" + String(i-1)+".bmp");} else {TBuffA->LoadFromFile(file+ "0" + String(i-1)+".bmp");} TBuffG->LoadFromFile(file+ "0" + String(i)+".bmp"); } } else { TBuffA->LoadFromFile(file+String(i-1)+".bmp"); TBuffG->LoadFromFile(file+String(i)+".bmp"); } h = 0; w = 0; m = 0; if (TBuffG->Height == i2 && TBuffG->Width == i1) { i3 = 0; s4 = 0; for (int bc = 0; bcCanvas->Pixels[ac][bc]; //save pixels as a TColor BG = TBuffG->Canvas->Pixels[ac][bc]; if (FG == BG) //if they are the same, increment the counter, and discard the pixels { i3++; w++; } if (FG != BG) //otherwise..... { if (i3 != 0) //if the counter is greater than zero, write the number of skipped pixels (includes a signature "//"). { out.put(''/''); out.put(''/''); out.write((char *)(&i3),sizeof(i3)); i3 = 0; s4++; } out.write((char *)(&BG),sizeof(BG)); //write the new pixel h++; } } } if (i3 != 0) { out.put(''/''); out.put(''/''); out.write((char *)(&i3),sizeof(i3)); //write the number of skipped pixels at the end of the current frame (if any) s4++; } } else { return false; } loge << "done: " << m << " pixels, " << h << " were unique, and " << w << " were copies -- " << (h*4) + (6*s4) << " bytes." << endl; x += h; s += (h*4) + (6*s4); } loge << "DGR Encoding complete." << endl << "DGR Size: " << s << " bytes." << endl << "Source bitmap size: " << (i1*i2*frames*4)+(54*frames) << " bytes."; out.close(); loge.close(); //close the file streams return true; } 
I said it was pretty basic, but it does what I want. The pixels (although really 24 bit) seem to include a padding block to align them to the 32 bit memory thingie.... though that top level byte seems critical (removal results in bad stuff happening....). and now the decoder..... this is where the problem is. If any more than about 15,000 pixels change in a single frame, everthing gets horrifically jerky.
  bool MASICi9::DrawDGR(String file,int x,int y,TCanvas* surface) { ifstream in(file.c_str(),ios::binary); //open file if (in.get() == ''D'') //check signature { if (in.get() == ''G'') { if (in.get() == ''R'') { test = false; //set default version c1 = in.get(); if (c1 == ''2'')//check actual version {test = true;} //the next lines read the header, frames, width and height if (!test) { in.read((char *)(&s4),2); in.read((char *)(&s1),2); in.read((char *)(&s2),2); i1 = s1; i2 = s2; } else { in.read((char *)(&s4),2); in.read((char *)(&i1),sizeof(i1)); in.read((char *)(&i2),sizeof(i2)); } TBuffG->Height = i2; //set bitmap height TBuffG->Width = i1; //set bitmap width for (int bc = 0; bcCanvas->Pixels[ac][bc] = FG; //store pixel to temporary bitmap } } surface->Draw(x,y,TBuffG); //draw bitmap to window for (int i = 1; i<=s4; i++) //read compressed frames { i3 = 0; m = 0; for (int bc = 0; bcCanvas->Pixels[ac][bc] = FG; //on mistake (ie: pixel has a value of "/" in it -- untested, never actually happened), form a pixel from known data and store to canvas. } } else { in.read((char *)(&FG),sizeof(FG)); //if no signature found, read a pixel and store to canvas. TBuffG->Canvas->Pixels[ac][bc] = FG; } } else { i3--; //if skipped pixels > 0, count down. } } } App->ProcessMessages(); //check the windows message pump if (!DGRPlayOK) //if told to stop playing, exit {return false;} surface->Draw(x,y,TBuffG); //draw frame to canvas } } } } in.close(); //close file stream return true; } 
Please help -- as a newbie programmer there are probably millions of ways to optimise that I can''t see. If you''ve looked at this and thought "freaky code" or somesuch, it''s because I''m using Borland C++ Builder 5, which handles all the DCs and thingies. Probably a mixed blessing, since my code has to go through even more layes of processing, but it suits my needs (apart from speed). --Cirian

##### Share on other sites
If looks like you are reading the file every frame, which is really really slow, especially since you are reading it in tiny chunks at a time. Usually you want to read everthing in and store it in memory, then just draw the appropriate sprite from memory. If you wanted to speed up the file decoding (its still not going to be fast enough to do every frame) read the whole file into memory at once, and work on it there.

##### Share on other sites
Thanks invective -- I now have one that makes an array of chars, then loads the file at the start in 64 bit chunks. Playback is about 8 times faster.... now on to optimising the file loading sequence......