Kann man diese funktion optimieren oder ersetzen?
-
Hi,
ich habe eine Funktion mit der ich Bitmaps spiegeln kann:
void flip (unsigned char *image, const int bytesPerLine, const int height) { unsigned char *line1 = new (std::nothrow) unsigned char [bytesPerLine]; unsigned char *line2 = new (std::nothrow) unsigned char [bytesPerLine]; int numLines = static_cast<int>(height/2); for (int i=0; i<numLines; ++i) { memcpy (line1, &image [i * bytesPerLine], bytesPerLine); memcpy (line2, &image [(height - 1 - i) * bytesPerLine], bytesPerLine); memcpy (&image [i * bytesPerLine], line2, bytesPerLine); memcpy (&image [(height - 1 - i) * bytesPerLine], line1, bytesPerLine); } delete [] line1; delete [] line2; }
jedoch die ist mir etwas zu groß, kann man da nicht etwas optimieren oder die funktion gar ersetzen durch eine bereichts vorhandene aus der STL?
Schonmal danke im voraus!
-
Der Einsatz von memcpy() lohnt sich in diesem Fall nicht, da Rasterzeilen ziemlich kurz sind (80 bytes bei 1600x1200).
Ausserdem braucht man nur einen Puffer, da man ja den Puffer gleich gespiegelt beschreiben kann, und hinterher in den Parameter-Puffer zurueckkopieren kann.
man koennte also schreiben:
void mirrory( char* inout, int bytesperrow, int rows ) { char* buf = new char [ bytesperrow * rows ]; for ( int y=0; y < rows; ++y ) { int src_offs = y * bytesperrow; int tgt_offs = ( rows - 1 - y ) * bytesperrow; for ( int x = 0; x < bytesperrow; ++x ) { buf[ tgt_offs + x ] = inout[ src_offs + x ]; } } memcpy( inout, buf, bytesperrow * rows ); delete [] buf; }
Falls ein Optimizer im C++ Compiler zur Verfuegung steht, sollte man ihn einschalten.
hoffe, das hilft.
-
Ich wette gleich kommt Volkard oder Humme an und schmeißen noch nen anderen Code hin der nur 4 Zeilen groß ist ^^
-
Weiß nicht, wonach Du optimieren willst. Die dynamische Speicherallozierung könnte man z.B. verringern:
unsigned char fastBuf[128]; unsigned char* line = bytesPerLine > 128 ? new unsigned char[bytesPerLine] : fastBuf; ... if(bytesPerLine > 128) delete[] line;
Oder ist der Code zu lang?
void flip(unsigned char *image, const int bytesPerLine, const int height) { int numLines = static_cast<int>(height / 2); for (int i = 0; i < numLines; ++i) std::swap_ranges(image + i * bytesPerLine, image + (i + 1) * bytesPerLine, image + (height - 1 - i) * bytesPerLine); }
(hab's nicht kompiliert - ohne Gewähr ;))
-
@tag
was braucht man denn für std::swap_ranges für nen header?
-
Müsste <algorithm> sein
-
Da schnafen mir die Fehler um die Ohren ohne ende.
-
void flip(unsigned char *image, const int bytesPerLine, const int height) { int numLines = static_cast<int>(height / 2); for (int i = 0; i < numLines; ++i) std::swap_ranges(image + i * bytesPerLine, image + (i + 1) * bytesPerLine, image + (height - 1 - i) * bytesPerLine); }
sehr fein. das verwenden voin swap_ranges war eine tolle idee.
ähm. wozu das static_cast??? das ist doch da nur blödsinniger code. willst du damit den int height/2 abrunden? oder magste einfach nur die blaue farbe im editor? dann hab ich was für dich: schreib in void-funktionen immer statt
throw bla;
lieber
return throw bla;
das ist schön blau und verwirrend isses auch, weil man genau wie bei deinem static_cast erstmal nachdenkt, warum das da wohl stehen mag.
warum const int im parameter? paranoia? die darf jeder haben, aber dann bitte richtig und numLines auch const machen. warum nicht auch unsigned char * (const?!) image? und keiner hat geprüft ob image==0 war. vielleicht ne referenz übergeben, denn referenzen können ja nach standard nicht 0 sein.
die berechnungen im aufruf von swap_ranges sind mir aber ein wenig groß geworden.
mein stil ist eher:
void flip(unsigned char * (const?!) image, const int bytesPerLine, const int height) { unsigned char* oben=image;//anfang erste zeile unsigned char* unten=image+bytesPerLine*(height-1);//anfang letzte zeile while(oben<unten){//solange die beden sich nicht getroffen haben //ja, non-standard. aber wer merkt das schon? swap_ranges(oben,oben+bytesPerLine,unten); oben+=bytesPerLine;//oben geht eine zeile runter unten-=bytesPerLine;//unten geht eine zeile hoch } }
Ich wette gleich kommt Volkard oder Humme an und schmeißen noch nen anderen Code hin der nur 4 Zeilen groß ist
so gut bin ich noch nicht. ich mach's lieber auf die alte tour. den code etwas dynamischer halten, den ablauf coden, statt nur fertige aggregate zusammenstecken. da werden die sachen einfacher, finde ich (und einer meint, ich würde das nur deshalb einfacher finden, weil ich die stl nicht gerafft hab
).
und wer kein swap_ranges hat, darf sich rugig eins selber schreiben. das tut garantiert nicht fürchterlich weh. eigentlich sollte jeder sowas immer mal selber schreiben, bevor er fremde benutzen tut.
-
Na, heute mit dem falschen Fuß aufgestenden, hä?
Mich würde interessieren, was daran non-standard ist.
-
Was meinst du mit
"Ja, non-standard"?