From: Fridrich S. <str...@us...> - 2008-07-23 09:54:04
|
Update of /cvsroot/libwpg/libwpg/src/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2337/src/lib Modified Files: WPG1Parser.cpp WPG1Parser.h WPG2Parser.cpp Log Message: rewrite the RLE decoding to not use manually allocated memory Index: WPG2Parser.cpp =================================================================== RCS file: /cvsroot/libwpg/libwpg/src/lib/WPG2Parser.cpp,v retrieving revision 1.76 retrieving revision 1.77 diff -u -d -r1.76 -r1.77 --- WPG2Parser.cpp 22 Jul 2008 15:36:49 -0000 1.76 +++ WPG2Parser.cpp 23 Jul 2008 09:53:55 -0000 1.77 @@ -171,9 +171,9 @@ long kxsin; long kysin; long txinteger; - short txfraction; + unsigned short txfraction; long tyinteger; - short tyfraction; + unsigned short tyfraction; long px; long py; @@ -1446,26 +1446,18 @@ tmpBufferSize = width*height; - // prepare the bitmap actual data - unsigned char* buffer = 0; - unsigned char* ptr = 0; - + std::vector<unsigned char> buffer; // plain data, uncompression if(compression_format==0) - { - buffer = new unsigned char[tmpBufferSize]; for(unsigned ii=0; ii < tmpBufferSize && m_input->tell() <= m_recordEnd; ii++) - buffer[ii] = readU8(); - } + buffer.push_back( readU8() ); // run-length encoding else if(compression_format==1) { unsigned char data[256]; bool xor_raster = false; - unsigned char* next_scanline = buffer; + unsigned next_scanline = 0; unsigned data_size = 1; - buffer = new unsigned char[tmpBufferSize]; - ptr = buffer; WPG_DEBUG_MSG(("Decoding RLE data\n")); @@ -1481,16 +1473,9 @@ { data_size = new_data_size; if (tmpBufferSize < data_size*width*height) - { tmpBufferSize = data_size*width*height; - if (buffer) - delete [] buffer; - buffer = new unsigned char[tmpBufferSize]; - } raster_len = data_size*width; } - ptr = buffer; - next_scanline = buffer; } // a run of black (index #0) @@ -1499,7 +1484,7 @@ unsigned count = 1 + readU8(); for( ; count ; --count ) for(unsigned j = 0; j < data_size && !m_input->atEOS(); j++) - *ptr++ = 0; + buffer.push_back( 0 ); } @@ -1510,7 +1495,7 @@ for( ; count ; --count ) for(unsigned j = 0; j < data_size && !m_input->atEOS(); j++) - *ptr++ = 255; + buffer.push_back( 255 ); } // extend previous run @@ -1519,17 +1504,22 @@ unsigned count = 1 + readU8(); for( ; count; --count) for(unsigned j = 0; j < data_size && !m_input->atEOS(); j++) - *ptr++ = data[j]; + buffer.push_back( data[j] ); } // repeat raster else if(opcode == 0xfe) { unsigned count = 1 + readU8(); - unsigned char* raster_source = ptr - raster_len; + if ( buffer.size() < raster_len ) + return; + unsigned raster_source = buffer.size() - raster_len; for( ; count; --count) for(unsigned long r = 0; r < raster_len; r++) - *ptr++ = *raster_source++; + { + unsigned char pixel = buffer[raster_source + r]; + buffer.push_back( pixel ); + } } // XOR @@ -1538,7 +1528,7 @@ // Xor-ing will happen when about to enter next raster // see after the last if down below xor_raster = true; - next_scanline = ptr + raster_len; + next_scanline = buffer.size() + raster_len; } // NOTE: the following two IFs here must be the last ones @@ -1551,7 +1541,7 @@ data[i] = readU8(); for( ; count; --count) for(unsigned j = 0; j < data_size; j++) - *ptr++ = data[j]; + buffer.push_back( data[j] ); } // simple copy @@ -1560,7 +1550,7 @@ unsigned count = opcode + 1; for( ; count; --count) for(unsigned j = 0; j < data_size && !m_input->atEOS(); j++) - *ptr++ = readU8(); + buffer.push_back( readU8() ); } // unreachable: only sentinel @@ -1571,16 +1561,16 @@ } // new raster/scanline? if necessary do the XOR now - if(xor_raster && (ptr >= next_scanline)) + if(xor_raster && buffer.size() >= next_scanline) { // reset, because XOR in one raster at a time xor_raster = false; // current raster must be XORed with previous raster - unsigned char* current = next_scanline - raster_len; - unsigned char* previous = current - raster_len; + unsigned current = next_scanline - raster_len; + unsigned previous = current - raster_len; for( unsigned long r = 0; r < raster_len; r++) - current[r] ^= previous[r]; + buffer[current++] ^= buffer[previous++]; } @@ -1590,7 +1580,7 @@ } // no buffer? format is unknown - if(!buffer) return; + if(!buffer.size()) return; // prepare the bitmap structure for the listener libwpg::WPGBitmap bitmap(width, height, m_vFlipped, m_hFlipped); @@ -1740,7 +1730,7 @@ #ifdef DEBUG // debugging only - if(buffer && 0) + if(buffer.size() && 0) { for(unsigned long x = 0; x < width; x++) for(unsigned long y = 0; y < height; y++) @@ -1750,9 +1740,6 @@ } } #endif - - // discard - delete [] buffer; } void WPG2Parser::handleObjectCapsule() Index: WPG1Parser.h =================================================================== RCS file: /cvsroot/libwpg/libwpg/src/lib/WPG1Parser.h,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- WPG1Parser.h 17 Jul 2008 14:41:57 -0000 1.17 +++ WPG1Parser.h 23 Jul 2008 09:53:55 -0000 1.18 @@ -31,6 +31,7 @@ #include "WPGXParser.h" #include "WPGBrush.h" #include "WPGPen.h" +#include <vector> class WPG1Parser : public WPGXParser { @@ -54,8 +55,8 @@ void handleCurvedPolyline(); - unsigned char* decodeRLE(int width, int height, int depth); - void fillPixels(libwpg::WPGBitmap& bitmap, unsigned char* buffer, int width, int height, int depth); + void decodeRLE(std::vector<unsigned char>& buffer, int width, int height, int depth); + void fillPixels(libwpg::WPGBitmap& bitmap, const unsigned char* buffer, int width, int height, int depth); void handleBitmapTypeOne(); void handleBitmapTypeTwo(); void handlePostscriptTypeOne(); Index: WPG1Parser.cpp =================================================================== RCS file: /cvsroot/libwpg/libwpg/src/lib/WPG1Parser.cpp,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- WPG1Parser.cpp 17 Jul 2008 15:38:19 -0000 1.42 +++ WPG1Parser.cpp 23 Jul 2008 09:53:55 -0000 1.43 @@ -503,28 +503,16 @@ WPG_DEBUG_MSG(("Curved Polyline\n")); } -// allocate a buffer (of specified bitmap size), then start decoding RLE data -// from the input stream to fill the buffer -// NOTE: delete the buffer by yourself! -unsigned char* WPG1Parser::decodeRLE(int width, int height, int depth) +void WPG1Parser::decodeRLE(std::vector<unsigned char>& buffer, int width, int height, int depth) { + buffer.clear(); if (depth <= 0 || width <= 0 || height <= 0) - return 0; + return; // round to the next byte unsigned scanline_width = (width * depth + 7)/8; - unsigned buffer_size = scanline_width * height; WPG_DEBUG_MSG(("Scanline width: %d\n", scanline_width)); - WPG_DEBUG_MSG(("Output size: %d\n", buffer_size)); - - // buffer for the result - unsigned char* buffer = new unsigned char[buffer_size]; - - if (!buffer) - return 0; - - // pointer to write decoded data - unsigned char* ptr = buffer; + WPG_DEBUG_MSG(("Output size: %d\n", scanline_width * height)); WPG_DEBUG_MSG(("Decoding RLE data\n")); for(; m_input->tell() < m_recordEnd; ) @@ -538,8 +526,8 @@ unsigned char pixel = (count > 0) ? readU8() : 0xff; if(count == 0) count = (int)readU8(); - for( ; count && ptr < buffer + buffer_size; --count) - *ptr++ = pixel; + for( ; count ; --count) + buffer.push_back( pixel ); } else { @@ -547,29 +535,34 @@ if(count > 0) { // literal byte copy - for( ; count && ptr < buffer + buffer_size; --count) - *ptr++ = readU8(); + for( ; count ; --count) + buffer.push_back( readU8() ); } else { // copy entire scan line count = (int)readU8(); - unsigned char* raster_source = ptr - scanline_width; - if (!raster_source || raster_source < buffer) - return 0; + if (buffer.size() < scanline_width ) + { + WPG_DEBUG_MSG(("Cannot copy the scanline, not enough data %li\n", (long)buffer.size())); + buffer.clear(); + return; + } + unsigned raster_source = buffer.size() - scanline_width; for( ; count; --count) - for(unsigned r = 0; r < scanline_width && ptr < buffer + buffer_size;) - *ptr++ = raster_source[r++]; + for(unsigned r = 0; r < scanline_width ; r++) + { + unsigned char pixel = buffer[raster_source + r]; + buffer.push_back( pixel ); + } } } } WPG_DEBUG_MSG(("Finish decoding RLE data\n")); - - return buffer; + WPG_DEBUG_MSG(("Buffer length: %li\n", (long)buffer.size())); } -void WPG1Parser::fillPixels(libwpg::WPGBitmap& bitmap, unsigned char* buffer, -int width, int height, int depth) +void WPG1Parser::fillPixels(libwpg::WPGBitmap& bitmap, const unsigned char* buffer, int width, int height, int depth) { // sanity if(!buffer) @@ -585,7 +578,7 @@ libwpg::WPGColor white(255, 255, 255); for(int y = 0; y < height; y++) { - unsigned char* buf = buffer + y * scanline_width; + const unsigned char* buf = buffer + y * scanline_width; for(int x = 0; x < width; x++) if(buf[x/8] & (0x80 >> (x & 7))) bitmap.setPixel(x, y, white); @@ -626,7 +619,7 @@ { for(int y = 0; y < height; y++) { - unsigned char* buf = buffer + y * scanline_width; + const unsigned char* buf = buffer + y * scanline_width; for(int x = 0; x < width; x++) { const libwpg::WPGColor& color = m_colorPalette[buf[x]]; @@ -685,12 +678,11 @@ bitmap.rect.x2 = (double)width/(double)hres; bitmap.rect.y2 = (double)height/(double)vres; - unsigned char* buffer = decodeRLE(width, height, depth); - if (buffer) + std::vector<unsigned char> buffer; + decodeRLE(buffer, width, height, depth); + if (buffer.size()) { - fillPixels(bitmap, buffer, width, height, depth); - delete [] buffer; - + fillPixels(bitmap, &buffer[0], width, height, depth); m_painter->drawBitmap(bitmap); } } @@ -751,12 +743,11 @@ bitmap.rect.x2 = (double)xs2/1200.0; bitmap.rect.y2 = (double)(ys2)/1200.0; - unsigned char* buffer = decodeRLE(width, height, depth); - if (buffer) + std::vector<unsigned char> buffer; + decodeRLE(buffer, width, height, depth); + if (buffer.size()) { - fillPixels(bitmap, buffer, width, height, depth); - delete [] buffer; - + fillPixels(bitmap, &buffer[0], width, height, depth); m_painter->drawBitmap(bitmap); } } |