picture::picture(const picture& im) { width=im.GetWidth(); height=im.GetHeight(); data = new u_char[3 * width * height]; memcpy(data, im.GetData(), 3 * width * height * sizeof(*data)); }
void picture_rep::internal_copy_from (int x, int y, picture src, int x1, int y1, int x2, int y2) { for (int yy= y1; yy < y2; yy++) for (int xx= x1; xx < x2; xx++) internal_set_pixel (x + xx, y + yy, src->internal_get_pixel (xx, yy)); }
void picture_rep::internal_copy_to (int x, int y, picture dest, int x1, int y1, int x2, int y2) { for (int yy= y1; yy < y2; yy++) for (int xx= x1; xx < x2; xx++) dest->internal_set_pixel (x + xx, y + yy, internal_get_pixel (xx, yy)); }
template<class C> raster<C> as_raster (picture pic) { if (pic->get_type () != picture_kind_helper<C>::kind) { picture rew= raster_picture (pic->get_width (), pic->get_height (), pic->get_origin_x (), pic->get_origin_y ()); pic->copy_to (rew); pic= rew; } raster_picture_rep<C>* rep= (raster_picture_rep<C>*) pic->get_handle (); return rep->r; }
string picture_as_eps (picture pic, int dpi) { (void) dpi; if (DEBUG_CONVERT) debug_convert<< "in picture_as_eps " <<LF; static const char* d= "0123456789ABCDEF"; int w_pt= pic->get_width (), h_pt= pic->get_height (); int ox= pic->get_origin_x (), oy= pic->get_origin_y (); string r; string sw= as_string (w_pt); string sh= as_string (h_pt); r << "%!PS-Adobe-3.0 EPSF-3.0\n%%Creator: TeXmacs\n%%BoundingBox: 0 0 " << sw << " " << sh << "\n\n% Created by picture_as_eps ()\n\n%%BeginProlog\nsave\n" << "countdictstack\nmark\nnewpath\n/showpage {} def\n/setpagedevice " << "{pop} def\n%%EndProlog\n%%Page 1 1\n" << "/max { 2 copy lt { exch } if pop } bind def\n" << "/ImageWidth " << sw << " def\n/ImageHeight " << sh << " def\nImageWidth ImageHeight max " << "ImageWidth ImageHeight max scale\n\n/ImageDatas\n\tcurrentfile\n\t" << "<< /Filter /ASCIIHexDecode >>\n\t/ReusableStreamDecode\n\tfilter\n"; int v, i= 0, j= 0, k= 0, l= 0; bool alpha= false; for (j=0; j < h_pt; j++) for (i=0; i < w_pt; i++) { color col= pic->get_pixel (i - ox, h_pt - 1 - j - oy); int rr, gg, bb, aa; get_rgb_color (col, rr, gg, bb, aa); if (aa != 255) alpha= true; } string mask; for (j= 0; j < h_pt; j++) { for (i=0; i < w_pt; i++) { l++; color col= pic->get_pixel (i - ox, h_pt - 1 - j - oy); int rr, gg, bb, aa; get_rgb_color (col, rr, gg, bb, aa); rr= (rr * aa + 255 * (255 - aa)) / 255; gg= (gg * aa + 255 * (255 - aa)) / 255; bb= (bb * aa + 255 * (255 - aa)) / 255; r << as_hexadecimal (rr, 2); r << as_hexadecimal (gg, 2); r << as_hexadecimal (bb, 2); if (l > 12) { r << "\n"; l= 0; } } if (alpha) { v = 0; for (i=0; i < w_pt; i++) { color col= pic->get_pixel (i - ox, h_pt - 1 - j - oy); int rr, gg, bb, aa; get_rgb_color (col, rr, gg, bb, aa); v += (aa <= 32) << (3 - i % 4); if (i % 4 == 3 || i + 1 == w_pt) { mask << d[v]; v= 0; k++; // Padding of the image data mask if (i + 1 == w_pt && k % 2 == 1) { mask << d[0]; k++; } // Code layout if (k >= 78) { mask << "\n"; k= 0; } } } } } r << ">\ndef\n\n"; if (alpha) { r << "/MaskDatas\n\tcurrentfile\n\t<< /Filter /ASCIIHexDecode >>\n" << "\t/ReusableStreamDecode\n\tfilter\n" << mask << ">\ndef\n\n" << "/TheMask\n<<\n\t/ImageType\t1\n\t/Width\t\tImageWidth\n\t/Height\t" << "\tImageHeight\n\t/BitsPerComponent 1\n\t/Decode [ 0 1 ]\n\t" << "/ImageMatrix [ ImageWidth 0 0 ImageWidth neg 0 ImageHeight ]\n\t" << "/DataSource MaskDatas\n>> def\n\n"; } r << "/TheImage\n<<\n\t/ImageType\t1\n\t/Width\t\tImageWidth\n\t/Height\t" << "\tImageHeight\n\t/BitsPerComponent 8\n\t/Decode [ 0 1 0 1 0 1 ]\n\t" << "/ImageMatrix [ ImageWidth 0 0 ImageWidth neg 0 ImageHeight ]\n\t" << "/DataSource ImageDatas\n>> def\n\n" << "/DeviceRGB setcolorspace\n"; if (alpha) { r << "<<\n\t/ImageType 3\n\t/InterleaveType 3\n\t/DataDict TheImage\n" << "\t/MaskDict TheMask\n>>"; } else { r << "\tTheImage"; } r << "\nimage\nshowpage\n%%Trailer\ncleartomark\ncountdictstack\n" << "exch sub { end } repeat\nrestore\n%%EOF\n"; return r; }
void woba_decode(picture & p, char * woba) { #if DEBUGOUTPUT std::cout << "===== NEXT BMAP =====" << endl; #endif int totalRectTop = 0, totalRectLeft = 0, totalRectBottom = 0, totalRectRight = 0; /* total rectangle for whole picture */ int maskBoundRectTop = 0, maskBoundRectLeft = 0, maskBoundRectBottom = 0, maskBoundRectRight = 0; /* mask bounding rect */ int pictureBoundRectTop = 0, pictureBoundRectLeft = 0, pictureBoundRectBottom = 0, pictureBoundRectRight = 0; /* picture bounding rect */ int maskDataLength = 0, pictureDataLength = 0; /* mask and picture data length */ int bx = 0, bx8 = 0, x = 0, y = 0; int rowwidth = 0, rowwidth8 = 0, height = 0; int dx = 0; int dy = 0; int repeat = 1; CBuf patternbuffer(8); CBuf buffer1; CBuf buffer2; int i = 0, j = 0; int opcode = 0; int operand = 0; CBuf operandata(256); int numberOfZeroBytes = 0, numberOfDataBytes = 0; int k = 0; /* -16 0 - block size & type (already stripped) -8 8 - block ID & filler (already stripped) 8 16 - something 12 24 - total rect 20 32 - mask rect 28 40 - picture rect 36 48 - nothing 48 56 - length 52 64 - start of mask (or bitmap if mask length == 0) */ #define MASK_START 52 #define INT16_AT(woba,pos) ntohs(*(u_int16_t*)(woba+pos)) #define INT32_AT(woba,pos) ntohl(*(u_int32_t*)(woba+pos)) totalRectTop = INT16_AT(woba,12); totalRectLeft = INT16_AT(woba,14); totalRectBottom = INT16_AT(woba,16); totalRectRight = INT16_AT(woba,18); maskBoundRectTop = INT16_AT(woba,20); maskBoundRectLeft = INT16_AT(woba,22); maskBoundRectBottom = INT16_AT(woba,24); maskBoundRectRight = INT16_AT(woba,26); pictureBoundRectTop = INT16_AT(woba,28); pictureBoundRectLeft = INT16_AT(woba,30); pictureBoundRectBottom = INT16_AT(woba,32); pictureBoundRectRight = INT16_AT(woba,34); maskDataLength = INT32_AT(woba,44); pictureDataLength = INT32_AT(woba,48); #if DEBUGOUTPUT std::cout << "Total Rect: " << totalRectLeft << "," << totalRectTop << "," << totalRectRight << "," << totalRectBottom << endl; std::cout << "Bitmap Rect: " << pictureBoundRectLeft << "," << pictureBoundRectTop << "," << pictureBoundRectRight << "," << pictureBoundRectBottom << endl; std::cout << "Mask Rect: " << maskBoundRectLeft << "," << maskBoundRectTop << "," << maskBoundRectRight << "," << maskBoundRectBottom << endl; std::cout << "Bitmap Size: " << pictureDataLength << endl; std::cout << "Mask Size: " << maskDataLength << endl; #endif p.reinit( totalRectRight -totalRectLeft, totalRectBottom -totalRectTop, 1, false); p.__directcopybmptomask(); /* clear the mask to zero */ i= MASK_START; /* decode mask */ if( maskDataLength ) { bx8 = maskBoundRectLeft & (~ 0x1F); // Get high 11 bits (mask out low 5 bits). bx = bx8 / 8; // Bitshift by 3? x = 0; y = maskBoundRectTop; rowwidth8 = ( (maskBoundRectRight & 0x1F)?((maskBoundRectRight | 0x1F)+1):maskBoundRectRight ) - (maskBoundRectLeft & (~ 0x1F)); rowwidth = rowwidth8 / 8; height = maskBoundRectBottom - maskBoundRectTop; dx = dy = 0; repeat = 1; // Build a 50% grey checkerboard pattern: patternbuffer[0] = patternbuffer[2] = patternbuffer[4] = patternbuffer[6] = 170; // Even rows: 170 == 10101010 binary. patternbuffer[1] = patternbuffer[3] = patternbuffer[5] = patternbuffer[7] = 85; // Odd rows: 85 == 01010101 binary. // Make both buffers large enough to hold a full row of pixels: buffer1.resize(rowwidth); buffer2.resize(rowwidth); j = 0; #if DEBUGOUTPUT std::cout << "DECODE MASK:" << endl; std::cout << "BX8: " << bx8 << endl << "BX: " << bx << endl << "X: " << x << endl << "Y: " << y << endl; std::cout << "RW8: " << rowwidth8 << endl << "RW: " << rowwidth << endl << "H: " << height << endl; #endif while( j < maskDataLength ) { opcode = (unsigned char)woba[i]; #if DEBUGOUTPUT std::cout << "Opcode: " << __hex(opcode) << endl; std::cout << "Repeat: " << repeat << endl; std::cout << "i: " << i << endl << "j: " << j << endl; std::cout << "x: " << x << endl << "y: " << y << endl; std::cout << "dx: " << dx << endl << "dy: " << dy << endl; #endif i++; j++; if( (opcode & 0x80) == 0 ) { /* zeros followed by data */ numberOfDataBytes = opcode >> 4; // nd = number of data bytes? numberOfZeroBytes = opcode & 15; // nz = number of zeroes? #if DEBUGOUTPUT std::cout << "nd: " << numberOfDataBytes << endl << "nz: " << numberOfZeroBytes << endl; #endif if( numberOfDataBytes ) { operandata.memcpy( 0, woba, i, numberOfDataBytes ); i += numberOfDataBytes; j += numberOfDataBytes; } while( repeat ) { for( k = numberOfZeroBytes; k > 0; k-- ) { buffer1[x] = 0; x++; } buffer1.memcpy( x, operandata, 0, numberOfDataBytes ); x += numberOfDataBytes; repeat--; } repeat = 1; } else if( (opcode & 0xE0) == 0xC0 ) { /* opcode & 1F * 8 bytes of data */ numberOfDataBytes = (opcode & 0x1F) * 8; #if DEBUGOUTPUT std::cout << "nd: " << numberOfDataBytes << endl; #endif if (numberOfDataBytes) { operandata.memcpy( 0, woba, i, numberOfDataBytes ); i += numberOfDataBytes; j += numberOfDataBytes; } while( repeat ) { buffer1.memcpy(x, operandata, 0, numberOfDataBytes); x += numberOfDataBytes; repeat--; } repeat = 1; } else if( (opcode & 0xE0) == 0xE0 ) { /* opcode & 1F * 16 bytes of zero */ numberOfZeroBytes = (opcode & 0x1F)*16; #if DEBUGOUTPUT std::cout << "nz: " << numberOfZeroBytes << endl; #endif while( repeat ) { for (k=numberOfZeroBytes; k>0; k--) { if( x < buffer1.size() ) buffer1[x] = 0; x++; } repeat--; } repeat=1; } if( (opcode & 0xE0) == 0xA0 ) // Repeat the next opcode a certain number of times. { /* repeat opcode */ repeat = (opcode & 0x1F); } else { switch (opcode) { case 0x80: /* uncompressed data */ x = 0; while( repeat ) { p.maskmemcopyin(woba+i, bx8, y, rowwidth); y++; repeat--; } repeat=1; i += rowwidth; j += rowwidth; break; case 0x81: /* white row */ x = 0; while( repeat ) { p.maskmemfill(0, bx8, y, rowwidth); y++; repeat--; } repeat=1; break; case 0x82: /* black row */ x = 0; while( repeat ) { p.maskmemfill(0xFF, bx8, y, rowwidth); y++; repeat--; } repeat=1; break; case 0x83: /* pattern */ operand = (unsigned char)woba[i]; #if DEBUGOUTPUT std::cout << "patt: " << __hex(operand) << endl; #endif i++; j++; x = 0; while( repeat ) { patternbuffer[y & 7] = operand; p.maskmemfill(operand, bx8, y, rowwidth); y++; repeat--; } repeat=1; break; case 0x84: /* last pattern */ x = 0; while( repeat ) { operand = patternbuffer[y & 7]; #if DEBUGOUTPUT std::cout << "patt: " << __hex(operand) << endl; #endif p.maskmemfill(operand, bx8, y, rowwidth); y++; repeat--; } repeat=1; break; case 0x85: /* previous row */ x = 0; while( repeat ) { p.maskcopyrow(y, y-1); y++; repeat--; } repeat=1; break; case 0x86: /* two rows back */ x = 0; while( repeat ) { p.maskcopyrow(y, y-2); y++; repeat--; } repeat=1; break; case 0x87: /* three rows back */ x = 0; while( repeat ) { p.maskcopyrow(y, y-3); y++; repeat--; } repeat = 1; break; case 0x88: dx = 16; dy = 0; break; case 0x89: dx = 0; dy = 0; break; case 0x8A: dx = 0; dy = 1; break; case 0x8B: dx = 0; dy = 2; break; case 0x8C: dx = 1; dy = 0; break; case 0x8D: dx = 1; dy = 1; break; case 0x8E: dx = 2; dy = 2; break; case 0x8F: dx = 8; dy = 0; break; default: /* it's not a repeat or a whole row */ if( x >= rowwidth ) { x = 0; if (dx) { buffer2.memcpy( 0, buffer1, 0, rowwidth ); for( k = rowwidth8 / dx; k > 0; k-- ) { buffer2.shiftnstr(0, rowwidth, dx); buffer1.xornstr(0, buffer2, 0, rowwidth); } } if (dy) { p.maskmemcopyout(buffer2, bx8, y-dy, rowwidth); buffer1.xornstr(0, buffer2, 0, rowwidth); } p.maskmemcopyin(buffer1.buf(), bx8, y, rowwidth); y++; } break; } } }
inline void copy_from (picture s) { internal_copy_from (0, 0, s, 0, 0, s->get_width (), s->get_height ()); }