/*************************************************************************** qfrpostscript.cpp ---------------------------- begin : 2005-06-23 copyright : (C) 2005 by Serghei Amelian email : serghei.amelian@gmail.com ***************************************************************************/ #include #include #include #include "../config.h" #include "qfrtiffio.h" #include "qfrpostscript.h" static const char *sBeginDocument = "%%!PS-Adobe-3.0\n" "%%%%Creator: QFaxReader " VERSION "\n" "%%%%Title: %s\n" "%%%%CreationDate: %s\n" "%%%%DocumentData: Clean7Bit\n" "%%%%Origin: 0 0\n" "%%%%BoundingBox: 0 0 %d %d\n" "%%%%Orientation: %s\n" "%%%%LanguageLevel: %d\n" "%%%%Pages: (atend)\n" "%%%%EndComments\n" "%%%%BeginSetup\n" "%s" "%%%%EndSetup\n"; static const char *sSetup = "gsave newpath clippath pathbbox grestore\n" " 4 2 roll 2 copy translate\n" " exch 3 1 roll sub 3 1 roll sub exch\n" " currentpagedevice /PageSize get aload pop\n" " exch 3 1 roll div 3 1 roll div abs exch abs\n" " 2 copy gt { exch } if pop\n" " dup 1 lt { dup scale } { pop } ifelse\n"; static const char *sEndDocument = "%%%%Trailer\n" "%%%%Pages: %d\n" "%%%%EOF\n"; static const char *sBeginPage = "%%%%Page: %d %d\n" "gsave\n" "%s" "100 dict begin\n"; static const char *sEndPage = "grestore\n" "showpage\n"; static const char *sRectangle = "newpath\n" "%d %d moveto\n" "%d 0 rlineto\n" "0 -%d rlineto\n" "-%d 0 rlineto\n" "0 %d rlineto\n" ".1 setlinewidth\n" "stroke\n"; static const char *sBeginImage = "gsave\n" "%d %d translate\n" "%d %d scale\n" "0 1 translate\n"; static const char *sBeginBWImage1 = "%%ImageData: %d %d 1 1 0 1 2 \"image\"\n" "/DataString %d string def\n" "%d %d %d [ %d 0 0 -%d 0 %d ]\n" "{ currentfile DataString readhexstring pop } bind image\n"; static const char *sBeginColorImage1 = "/bwproc {\n" " rgbproc\n" " dup length 3 idiv string 0 3 0\n" " 5 -1 roll {\n" " add 2 1 roll 1 sub dup 0 eq {\n" " pop 3 idiv\n" " 3 -1 roll\n" " dup 4 -1 roll\n" " dup 3 1 roll\n" " 5 -1 roll put\n" " 1 add 3 0\n" " } { 2 1 roll } ifelse\n" " } forall\n" " pop pop pop\n" "} def\n" "/colorimage where {pop} {\n" " /colorimage {pop pop /rgbproc exch def {bwproc} image} bind def\n" "} ifelse\n" "%ImageData: 808 630 8 3 0 1 2 \"false 3 colorimage\"\n" "/line 2424 string def\n" "808 630 8\n" "[808 0 0 -630 0 630]\n" "{currentfile line readhexstring pop} bind\n" "false 3 colorimage\n"; static const char *sBeginImage2 = "/DeviceGray setcolorspace\n" "{ %% exec\n" "/im_stream currentfile /ASCII85Decode filter def\n" "<<\n" "/ImageType 1\n" "/Width %d\n" "/Height %d\n" "/ImageMatrix [ %d 0 0 -%d 0 %d ]\n" "/BitsPerComponent 1\n" "/Interpolate true\n" "/Decode [0 1]\n" "/DataSource im_stream\n" " <<\n" " /EndOfLine true\n" " /EndOfBlock false\n" " /EncodedByteAlign true\n" " /Rows %d\n" " >> /CCITTFaxDecode filter\n" ">> image\n" "im_stream status { im_stream flushfile } if\n" "}\n" "exec\n"; static const char *sEndImage = "grestore\n"; QfrPostscript::QfrPostscript(FILE *f) : f(f), pages(0) { } QfrPostscript::~QfrPostscript() { } bool QfrPostscript::beginDocument(const char *title, int pagesPerSheet, int width, int height, int top, int bottom, int left, int right, int level, bool border) { spacing = 6; m_pagesPerSheet = pagesPerSheet; m_border = border; pages = images = 0; m_width = width; m_height = height; m_top = top; m_bottom = bottom; m_left = left; m_right = right; m_level = level; m_landscape = (2 == pagesPerSheet); return 0 <= fprintf(f, sBeginDocument, title, QDateTime::currentDateTime().toString().latin1(), width, height, m_landscape ? "Landscape" : "Portrait", level, 1 == level ? "" : sSetup); } bool QfrPostscript::endDocument() { QString s1, s2; if(pages) s1 = sEndPage; s2.sprintf(sEndDocument, pages); PUTS(s1 + s2); return true; } bool QfrPostscript::newPage() { QString s1, s2; if(pages) s1 = sEndPage; pages++; s2.sprintf(sBeginPage, pages, pages, m_landscape ? "90 rotate\n" : ""); PUTS(s1 + s2); return true; } bool QfrPostscript::drawRectangle(int x, int y, int w, int h) { QString s1; s1.sprintf(sRectangle, x + m_left, (m_landscape ? 0 : m_height) - m_top - y, w, h, w, h); PUTS(s1); return true; } bool QfrPostscript::pushImage(QfrTiffIO &tif) { if(images >= m_pagesPerSheet) images = 0; if(!images) newPage(); int x = images % 2 * availWidth(); int y = ((images & 2) >> 1) * availHeight(); int w = availWidth(); int h = availHeight(); if(x) x += spacing; if(y) y += spacing; if(1 == m_level) { if(!drawLevel1Image(x, y, w, h, tif)) return false; } else { if(!drawLevel2Image(x, y, w, h, tif)) return false; } if(m_border) if(!drawRectangle(x, y, w, h)) return false; images++; return true; } int QfrPostscript::availWidth() const { int totalWidth = (m_landscape ? m_height : m_width) - m_left - m_right - (m_pagesPerSheet == 1 ? 0 : spacing); return totalWidth / (m_pagesPerSheet == 1 ? 1 : 2); } int QfrPostscript::availHeight() const { int totalHeight = (m_landscape ? m_width : m_height) - m_top - m_bottom - (m_pagesPerSheet == 1 ? 0 : spacing); return totalHeight / (m_pagesPerSheet == 4 ? 2 : 1); } bool QfrPostscript::drawLevel1Image(int x, int y, int w, int h, QfrTiffIO &tif) { x += m_left; y += m_top; uint32 iw, ih; tif.GetField(TIFFTAG_IMAGEWIDTH, &iw); tif.GetField(TIFFTAG_IMAGELENGTH, &ih); float xres, yres; if(!tif.GetField(TIFFTAG_XRESOLUTION, &xres)) xres = 300.; if(!tif.GetField(TIFFTAG_YRESOLUTION, &yres)) yres = 300.; int nw = (int)round((iw / xres) * 72); int nh = (int)round((ih / yres) * 72); float ratio = (float)nh / (float)nw; if(nw > w) { nw = w; nh = (uint32)round(nw * ratio); } if(nh > h) { nh = h; nw = (uint32)round(nh / ratio); } w = nw; h = nh; // photometric interpretation short pmi = 0; tif.GetField(TIFFTAG_PHOTOMETRIC, &pmi); // bits per sample short bits = 1; tif.GetField(TIFFTAG_BITSPERSAMPLE, &bits); // samples per pixel short samples = 1; tif.GetField(TIFFTAG_SAMPLESPERPIXEL, &samples); //if(3 > pmi && 1 == samples) return drawLevel1BWImage(x, y, w, h, iw, ih, bits, 0 == pmi, tif); return drawLevel1ColorImage(x, y, w, h, iw, ih, tif); } bool QfrPostscript::drawLevel1BWImage(int x, int y, int w, int h, int iw, int ih, int bits, bool minIsWhite, QfrTiffIO &tif) { tsize_t len = tif.ScanlineSize(); QString s1, s2; s1.sprintf(sBeginImage, x, (m_landscape ? 0 : m_height) - y - h * 2, w, h); s2.sprintf(sBeginBWImage1, iw, ih, len, iw, ih, bits, iw, ih, ih); PUTS(s1 + s2); QfrAsciiHexEncoder enc(f); enc.begin(); uchar *buf = new uchar[len]; for(int row = 0; row < ih; row++) { tif.ReadScanline(buf, row); if(minIsWhite) for(register int i = 0; i < len; i++) buf[i] = ~buf[i]; enc.encode(buf, len); } delete [] buf; enc.end(); PUTS(sEndImage); return true; } bool QfrPostscript::drawLevel1ColorImage(int x, int y, int w, int h, int iw, int ih, QfrTiffIO &tif) { QString s1, s2; s1.sprintf(sBeginImage, x, (m_landscape ? 0 : m_height) - y - h * 2, w, h); s2.sprintf(sBeginColorImage1); PUTS(s1 + s2); QImage image(iw, ih, 32); //tif.ReadRGBAImageOriented(iw, ih, (uint32*)image.bits(), ORIENTATION_TOPLEFT); tif.ReadRGBAImage(iw, ih, (uint32*)image.bits()); //image = image.swapRGB(); QfrAsciiHexEncoder enc(f); enc.begin(); enc.encode(image.bits(), iw * ih * sizeof(uint32)); enc.end(); PUTS(sEndImage); return true; } bool QfrPostscript::drawLevel2Image(int x, int y, int w, int h, QfrTiffIO &tif) { useImagemask = false; ascii85 = true; interpolate = true; level3 = (3 == m_level); alpha = 0; // -------------------- x += m_left; y += m_top; uint32 iw, ih; tif.GetField(TIFFTAG_IMAGEWIDTH, &iw); tif.GetField(TIFFTAG_IMAGELENGTH, &ih); float xres, yres; if(!tif.GetField(TIFFTAG_XRESOLUTION, &xres)) xres = 300.; if(!tif.GetField(TIFFTAG_YRESOLUTION, &yres)) yres = 300.; uint32 nw = (int)round((iw / xres) * 72); uint32 nh = (int)round((ih / yres) * 72); float ratio = (float)nh / (float)nw; if(nw > (uint32)w) { nw = w; nh = (uint32)round(nw * ratio); } if(nh > (uint32)h) { nh = h; nw = (uint32)round(nh / ratio); } w = nw; h = nh; QString s1; s1.sprintf(sBeginImage, x, (m_landscape ? 0 : m_height) - y - h * 2, w, h); PUTS(s1); PUTS(level2ColorSpace(tif)); PUTS(level2ImageDict(tif, iw, ih)); PUTS("exec\n"); // -------------------------- uint16 samplesperpixel = 0; tif.GetField(TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); uint16 extrasamples = 0; uint16* sampleinfo; tif.GetField(TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); // -------------------------- uint32 num_chunks, *bc; int tiled_image = tif.IsTiled(); if(tiled_image) { num_chunks = tif.NumberOfTiles(); tif.GetField(TIFFTAG_TILEBYTECOUNTS, &bc); } else { num_chunks = tif.NumberOfStrips(); tif.GetField(TIFFTAG_STRIPBYTECOUNTS, &bc); } tsize_t chunk_size; if(use_rawdata) { chunk_size = (tsize_t)bc[0]; for(uint32 chunk_no = 1; chunk_no < num_chunks; chunk_no++) if((tsize_t)bc[chunk_no] > chunk_size) chunk_size = (tsize_t)bc[chunk_no]; } else { if(tiled_image) chunk_size = tif.TileSize(); else chunk_size = tif.StripSize(); } unsigned char *buf_data = (unsigned char*)_TIFFmalloc(chunk_size); if(!buf_data) { qWarning("Can't alloc %u bytes for %s.", chunk_size, tiled_image ? "tiles" : "strips"); return false; } QfrAscii85Encoder enc(f); tsize_t byte_count; uint16 fillorder = 0; tif.GetFieldDefaulted(TIFFTAG_FILLORDER, &fillorder); for(uint32 chunk_no = 0; chunk_no < num_chunks; chunk_no++) { enc.begin(); if(use_rawdata) { if(tiled_image) byte_count = tif.ReadRawTile(chunk_no, buf_data, chunk_size); else byte_count = tif.ReadRawStrip(chunk_no, buf_data, chunk_size); if(fillorder == FILLORDER_LSB2MSB) TIFFReverseBits(buf_data, byte_count); } else { if(tiled_image) byte_count = tif.ReadEncodedTile(chunk_no, buf_data, chunk_size); else byte_count = tif.ReadEncodedStrip(chunk_no, buf_data, chunk_size); } if(byte_count < 0) { qWarning("Can't read %s %d.", tiled_image ? "tile" : "strip", chunk_no); } /* * For images with alpha, matte against a white background; * i.e. Cback * (1 - Aimage) where Cback = 1. We will fill the * lower part of the buffer with the modified values. * * XXX: needs better solution */ if(alpha) { int adjust, i, j = 0; int ncomps = samplesperpixel - extrasamples; for(i = 0; i < byte_count; i+=samplesperpixel) { adjust = 255 - buf_data[i + ncomps]; switch (ncomps) { case 1: buf_data[j++] = buf_data[i] + adjust; break; case 2: buf_data[j++] = buf_data[i] + adjust; buf_data[j++] = buf_data[i+1] + adjust; break; case 3: buf_data[j++] = buf_data[i] + adjust; buf_data[j++] = buf_data[i+1] + adjust; buf_data[j++] = buf_data[i+2] + adjust; break; } } byte_count -= j; } if (ascii85) enc.encode(buf_data, byte_count); enc.end(); } PUTS(sEndImage); // -------------------------- return true; } static int checkcmap(int n, uint16 *r, uint16 *g, uint16 *b) { while(n-- > 0) if(*r++ >= 256 || *g++ >= 256 || *b++ >= 256) return 16; qWarning("Assuming 8-bit colormap"); return 8; } inline int CVT(int x) { return (((x) * 255) / ((1L<<16)-1)); } QString QfrPostscript::level2ColorSpace(QfrTiffIO &tif) { QString res, tmp; uint16 *rmap, *gmap, *bmap; int i, num_colors; const char * colorspace_p; uint16 photometric = 0; tif.GetField(TIFFTAG_PHOTOMETRIC, &photometric); short bitspersample = 1; tif.GetField(TIFFTAG_BITSPERSAMPLE, &bitspersample); switch(photometric) { case PHOTOMETRIC_SEPARATED: colorspace_p = "CMYK"; break; case PHOTOMETRIC_RGB: colorspace_p = "RGB"; break; default: colorspace_p = "Gray"; } /* * Set up PostScript Level 2 colorspace according to * section 4.8 in the PostScript refenence manual. */ res.append("% PostScript Level 2 only.\n"); if(PHOTOMETRIC_PALETTE != photometric) { if(PHOTOMETRIC_YCBCR == photometric) { // MORE CODE HERE } res.append(tmp.sprintf("/Device%s setcolorspace\n", colorspace_p)); return res; } /* * Set up an indexed/palette colorspace */ num_colors = (1 << bitspersample); if(!tif.GetField(TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) { qWarning("Palette image w/o \"Colormap\" tag"); return ""; } if(checkcmap(num_colors, rmap, gmap, bmap) == 16) for(i = 0; i < num_colors; i++) { rmap[i] = CVT(rmap[i]); gmap[i] = CVT(gmap[i]); bmap[i] = CVT(bmap[i]); } res.append(tmp.sprintf("[ /Indexed /DeviceRGB %d", num_colors - 1)); QfrAscii85Encoder enc(f); if(ascii85) { } else //fputs(" <", fd); for (i = 0; i < num_colors; i++) if(ascii85) { enc.put((unsigned char)rmap[i]); enc.put((unsigned char)gmap[i]); enc.put((unsigned char)bmap[i]); } ///} else { /// fputs((i % 8) ? " " : "\n ", fd); /// fprintf(fd, "%02x%02x%02x", /// rmap[i], gmap[i], bmap[i]); ///} ///if (ascii85) /// Ascii85Flush(fd); ///else /// fputs(">\n", fd); res.append("] setcolorspace\n"); return res; } QString QfrPostscript::level2ImageDict(QfrTiffIO &tif, int w, int h) { QString result, tmp; // ------------------------ short bitspersample = 1; tif.GetField(TIFFTAG_BITSPERSAMPLE, &bitspersample); tsize_t tf_numberstrips = tif.NumberOfStrips(); tsize_t tf_rowsperstrip = 0; tif.GetField(TIFFTAG_ROWSPERSTRIP, &tf_rowsperstrip); uint16 planarconfiguration = 0; tif.GetField(TIFFTAG_PLANARCONFIG, &planarconfiguration); uint16 samplesperpixel = 0; tif.GetField(TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); uint16 extrasamples = 0; uint16* sampleinfo; tif.GetField(TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); uint16 photometric = 0; tif.GetField(TIFFTAG_PHOTOMETRIC, &photometric); uint16 compression = 0; tif.GetField(TIFFTAG_COMPRESSION, &compression); // ------------------------ uint32 tile_width, tile_height; uint16 predictor, minsamplevalue, maxsamplevalue; int repeat_count; char im_h[64], im_x[64], im_y[64]; char *imageOp = "image"; if(useImagemask && (bitspersample == 1)) imageOp = "imagemask"; strcpy(im_x, "0"); sprintf(im_y, "%lu", (long) h); sprintf(im_h, "%lu", (long) h); tile_width = w; tile_height = h; if(tif.IsTiled()) { repeat_count = tif.NumberOfTiles(); tif.GetField(TIFFTAG_TILEWIDTH, &tile_width); tif.GetField(TIFFTAG_TILELENGTH, &tile_height); if(tile_width > w || tile_height > h || (w % tile_width) != 0 || (h % tile_height != 0)) result.append("0 0 1 1 rectclip\n"); if(tile_width < w) { result.append("/im_x 0 def\n"); strcpy(im_x, "im_x neg"); } if(tile_height < h) { result.append("/im_y 0 def\n"); sprintf(im_y, "%lu im_y sub", (unsigned long)h); } } else { repeat_count = tf_numberstrips; tile_height = tf_rowsperstrip; if(tile_height > h) tile_height = h; if(repeat_count > 1) { result.append("/im_y 0 def\n"); result.append(tmp.sprintf("/im_h %lu def\n", (unsigned long)tile_height)); strcpy(im_h, "im_h"); sprintf(im_y, "%lu im_y sub", (unsigned long) h); } } result.append("{ % exec\n"); if(repeat_count > 1) result.append(tmp.sprintf("%d { %% repeat\n", repeat_count)); if (ascii85) result.append(" /im_stream currentfile /ASCII85Decode filter def\n"); result.append(" <<\n /ImageType 1\n"); result.append(tmp.sprintf(" /Width %lu\n", (unsigned long)tile_width)); /* * Workaround for some software that may crash when last strip * of image contains fewer number of scanlines than specified * by the `/Height' variable. So for stripped images with multiple * strips we will set `/Height' as `im_h', because one is * recalculated for each strip - including the (smaller) final strip. * For tiled images and images with only one strip `/Height' will * contain number of scanlines in tile (or image height in case of * one-stripped image). */ if(tif.IsTiled() || tf_numberstrips == 1) result.append(tmp.sprintf(" /Height %lu\n", (unsigned long)tile_height)); else result.append(" /Height im_h\n"); if (planarconfiguration == PLANARCONFIG_SEPARATE && samplesperpixel > 1) result.append(" /MultipleDataSources true\n"); result.append(tmp.sprintf( " /ImageMatrix [ %lu 0 0 %ld %s %s ]\n" " /BitsPerComponent %d\n" " /Interpolate %s\n", (unsigned long)w, -(long)h, im_x, im_y, bitspersample, (interpolate ? "true" : "false")) ); switch(samplesperpixel - extrasamples) { case 1: switch (photometric) { case PHOTOMETRIC_MINISBLACK: result.append(" /Decode [0 1]\n"); break; case PHOTOMETRIC_MINISWHITE: switch (compression) { case COMPRESSION_CCITTRLE: case COMPRESSION_CCITTRLEW: case COMPRESSION_CCITTFAX3: case COMPRESSION_CCITTFAX4: result.append(" /Decode [0 1]\n"); break; default: result.append(" /Decode [1 0]\n"); break; } break; case PHOTOMETRIC_PALETTE: tif.GetFieldDefaulted(TIFFTAG_MINSAMPLEVALUE, &minsamplevalue); tif.GetFieldDefaulted(TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue); result.append(tmp.sprintf(" /Decode [%u %u]\n", minsamplevalue, maxsamplevalue)); break; default: result.append(" /Decode [0 1]\n"); break; } break; case 3: switch (photometric) { case PHOTOMETRIC_RGB: result.append(" /Decode [0 1 0 1 0 1]\n"); break; case PHOTOMETRIC_MINISWHITE: case PHOTOMETRIC_MINISBLACK: default: result.append(" /Decode [0 1 0 1 0 1]\n"); break; } break; case 4: result.append(" /Decode [0 1 0 1 0 1 0 1]\n"); break; } result.append(" /DataSource"); if(planarconfiguration == PLANARCONFIG_SEPARATE && samplesperpixel > 1) result.append(" ["); if(ascii85) result.append(" im_stream"); else result.append(" currentfile /ASCIIHexDecode filter"); use_rawdata = TRUE; switch(compression) { case COMPRESSION_NONE: // 1: uncompressed break; case COMPRESSION_CCITTRLE: // 2: CCITT modified Huffman RLE case COMPRESSION_CCITTRLEW: // 32771: #1 w/ word alignment case COMPRESSION_CCITTFAX3: // 3: CCITT Group 3 fax encoding case COMPRESSION_CCITTFAX4: // 4: CCITT Group 4 fax encoding result.append("\n\t<<\n"); if(COMPRESSION_CCITTFAX3 == compression) { uint32 g3_options; result.append("\t /EndOfLine true\n"); result.append("\t /EndOfBlock false\n"); if (!tif.GetField(TIFFTAG_GROUP3OPTIONS, &g3_options)) g3_options = 0; if (g3_options & GROUP3OPT_2DENCODING) result.append(tmp.sprintf("\t /K %s\n", im_h)); if (g3_options & GROUP3OPT_UNCOMPRESSED) result.append("\t /Uncompressed true\n"); if (g3_options & GROUP3OPT_FILLBITS) result.append("\t /EncodedByteAlign true\n"); } else if(COMPRESSION_CCITTFAX4 == compression) { uint32 g4_options; result.append("\t /K -1\n"); tif.GetFieldDefaulted(TIFFTAG_GROUP4OPTIONS, &g4_options); if(GROUP4OPT_UNCOMPRESSED & g4_options) result.append("\t /Uncompressed true\n"); } if(!(tile_width == w && w == 1728U)) result.append(tmp.sprintf("\t /Columns %lu\n", (unsigned long)tile_width)); result.append(tmp.sprintf("\t /Rows %s\n", im_h)); if(COMPRESSION_CCITTRLE == compression || COMPRESSION_CCITTRLEW == compression) result.append("\t /EncodedByteAlign true\n\t /EndOfBlock false\n"); if(PHOTOMETRIC_MINISBLACK == photometric) result.append("\t /BlackIs1 true\n"); result.append("\t>> /CCITTFaxDecode filter"); break; case COMPRESSION_LZW: // 5: Lempel-Ziv & Welch tif.GetFieldDefaulted(TIFFTAG_PREDICTOR, &predictor); if(predictor == 2) result.append( tmp.sprintf("\n\t<<\n\t /Predictor %u\n\t /Columns %lu\n\t /Colors %u\n\t /BitsPerComponent %u\n\t>>", predictor, (unsigned long)tile_width, samplesperpixel, bitspersample)); result.append(" /LZWDecode filter"); break; case COMPRESSION_DEFLATE: /* 5: ZIP */ case COMPRESSION_ADOBE_DEFLATE: if(level3) { tif.GetFieldDefaulted(TIFFTAG_PREDICTOR, &predictor); if(predictor > 1) result.append( tmp.sprintf("\t %% PostScript Level 3 only.\n\t<<\n\t /Predictor %u\n\t /Columns %lu\n\t /Colors %u\n\t /BitsPerComponent %u\n\t>>", predictor, (unsigned long)tile_width, samplesperpixel, bitspersample)); result.append(" /FlateDecode filter"); } else use_rawdata = FALSE ; break; case COMPRESSION_PACKBITS: /* 32773: Macintosh RLE */ result.append(" /RunLengthDecode filter"); use_rawdata = TRUE; break; case COMPRESSION_OJPEG: /* 6: !6.0 JPEG */ case COMPRESSION_JPEG: /* 7: %JPEG DCT compression */ use_rawdata = FALSE; break; case COMPRESSION_NEXT: /* 32766: NeXT 2-bit RLE */ case COMPRESSION_THUNDERSCAN: /* 32809: ThunderScan RLE */ case COMPRESSION_PIXARFILM: /* 32908: Pixar companded 10bit LZW */ case COMPRESSION_JBIG: /* 34661: ISO JBIG */ use_rawdata = FALSE; break; case COMPRESSION_SGILOG: /* 34676: SGI LogL or LogLuv */ case COMPRESSION_SGILOG24: /* 34677: SGI 24-bit LogLuv */ use_rawdata = FALSE; break; default: use_rawdata = FALSE; break; } if(PLANARCONFIG_SEPARATE == planarconfiguration && samplesperpixel > 1) { uint16 i; // NOTE: This code does not work yet... for (i = 1; i < samplesperpixel; i++) result.append(" dup"); result.append(" ]"); } result.append(tmp.sprintf("\n >> %s\n", imageOp)); if(ascii85) result.append(" im_stream status { im_stream flushfile } if\n"); if(repeat_count > 1) { if(tile_width < w) { result.append(tmp.sprintf(" /im_x im_x %lu add def\n", (unsigned long)tile_width)); if(tile_height < h) result.append( tmp.sprintf(" im_x %lu ge {\n /im_x 0 def\n /im_y im_y %lu add def\n } if\n", (unsigned long)w, (unsigned long) tile_height)); } if(tile_height < h) { if (tile_width >= w) { result.append(tmp.sprintf(" /im_y im_y %lu add def\n", (unsigned long) tile_height)); if(!tif.IsTiled()) result.append( tmp.sprintf(" /im_h %lu im_y sub dup %lu gt { pop %lu } if def\n", (unsigned long)h, (unsigned long)tile_height, (unsigned long)tile_height)); } } result.append("} repeat\n"); } result.append("}\n"); return result; }