diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index b38af4d..e73c292 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -1274,6 +1274,84 @@ void HtmlOutputDev::drawChar(GfxState *state, double x, double y, pages->addChar(state, x, y, dx, dy, originX, originY, u, uLen); } +// based on code from pdf2xml +static void getImageFlip( GfxState *state, GBool &xFlip, GBool &yFlip ) +{ + double xt, yt, wt, ht; + GBool rotate; + + // get image position and size + //state->transform(0, 0, &xt, &yt); + state->transformDelta(1, 1, &wt, &ht); + + state->transformDelta(1, 0, &xt, &yt); + + rotate = fabs(xt) < fabs(yt); + + if (rotate) { + xFlip = ht < 0; + yFlip = wt > 0; + } else { + xFlip = wt < 0; + yFlip = ht > 0; + } +} + + +static void imageFlipY( unsigned char **rowPoiners, int rowCount ) +{ + for (int i = 0; igetLine(); + png_byte *row = (png_byte *) gmalloc(3 * width); // 3 bytes/pixel: RGB for (int x = 0; x < width; x++) { colorMap->getRGB(p, &rgb); // Write the RGB pixels into the row @@ -1370,20 +1455,15 @@ void HtmlOutputDev::drawPngImage(GfxState *state, Stream *str, int width, int he p += colorMap->getNumPixelComps(); } - if (!writer->writeRow(row_pointer)) { - delete writer; - fclose(f1); - return; - } + // Buffer the row + rows[y] = row; } - gfree(row); imgStr->close(); delete imgStr; } else { // isMask == true int bytes_per_row = ((width + 7) / 8); Guchar *bit_row = (Guchar *)gmalloc( bytes_per_row ); - Guchar *png_row = (Guchar *)gmalloc( width ); str->reset(); for (int ri = 0; ri < height; ++ri) @@ -1396,35 +1476,48 @@ void HtmlOutputDev::drawPngImage(GfxState *state, Stream *str, int width, int he delete writer; fclose(f1); gfree(bit_row); - gfree(png_row); + freeRows( rows, height ); return; } } + Guchar *png_row = (Guchar *)gmalloc( width ); + // convert bits into a bytes for PNG for(int i = 0; i < width; i++) png_row[i] = ((bit_row[i/8]) & (1<<(7-(i%8)))) ? 0x00 : 0xff ; // invert for PNG - if (!writer->writeRow( &png_row )) - { - error(errIO, -1, "Failed to write into PNG '%s'", fName->getCString()); - delete writer; - fclose(f1); - gfree(bit_row); - gfree(png_row); - return; - } + rows[ri] = png_row; } + gfree(bit_row); - gfree(png_row); } - str->close(); + // flip by Y + if (yFlip) + imageFlipY( rows, height ); + + // flip by X + if (xFlip) + for(int i=0; iwritePointers( rows, height )) + { + delete writer; + fclose(f1); + freeRows( rows, height ); + return; + } + writer->close(); delete writer; fclose(f1); + freeRows( rows, height ); + pages->addImage(fName, state); #else return; @@ -1439,9 +1532,22 @@ void HtmlOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, OutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg); return; } + +#ifdef ENABLE_LIBPNG + // we can flip only in presence of PNG library during + // conversion into a PNG since otherwise JPEG is simply dumped + // as it is on disk + GBool xFlip, yFlip; + getImageFlip(state, xFlip, yFlip); + + GBool forcePNG = xFlip || yFlip; +#else + GBool forcePNG = false; +#endif + // dump JPEG file - if (dumpJPEG && str->getKind() == strDCT) { + if (!forcePNG && dumpJPEG && str->getKind() == strDCT) { drawJpegImage(state, str); } else { @@ -1462,11 +1568,24 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, maskColors, inlineImg); return; } + +#ifdef ENABLE_LIBPNG + // we can flip only in presence of PNG library during + // conversion into a PNG since otherwise JPEG is simply dumped + // as it is on disk + GBool xFlip, yFlip; + getImageFlip(state, xFlip, yFlip); + + GBool forcePNG = xFlip || yFlip; +#else + GBool forcePNG = false; +#endif + /*if( !globalParams->getErrQuiet() ) printf("image stream of kind %d\n", str->getKind());*/ // dump JPEG file - if (dumpJPEG && str->getKind() == strDCT) { + if (!forcePNG && dumpJPEG && str->getKind() == strDCT) { drawJpegImage(state, str); } else {