[poppler] PNG images for pdftohtml: patch
Warren Toomey
poppler at tuhs.org
Tue Sep 30 22:37:29 PDT 2008
All, apologies for the noise on the list. The attached patch adds PNG output
to pdftohtml for non-DCT images, replacing the code that I submitted as
http://lists.freedesktop.org/archives/poppler/2008-September/004113.html.
The patch also ensures that pdftohtml inserts the correct image filename in
the <img src=""> output.
The utils/Makefile will need to be patched to include -lpng, and the config
system tweaked to search for libpng and define ENABLE_LIBPNG if it exists.
I will resubmit my reflow patch soon, and then I'll go quiet :)
Thanks,
Warren
-------------- next part --------------
--- HtmlOutputDev.cc 2008/09/30 00:18:37 1.1
+++ HtmlOutputDev.cc 2008/10/01 05:22:08
@@ -31,12 +31,17 @@
#ifdef ENABLE_LIBJPEG
#include "DCTStream.h"
#endif
+#define ENABLE_LIBPNG
+#ifdef ENABLE_LIBPNG
+#include "png.h"
+#endif
#include "GlobalParams.h"
#include "HtmlOutputDev.h"
#include "HtmlFonts.h"
int HtmlPage::pgNum=0;
int HtmlOutputDev::imgNum=1;
+GooList * HtmlOutputDev::imgList= new GooList();
extern double scale;
extern GBool complexMode;
@@ -741,22 +747,24 @@
else
{
fprintf(f,"<A name=%d></a>",pageNum);
- GooString* fName=basename(DocName);
- for (int i=1;i<HtmlOutputDev::imgNum;i++)
- fprintf(f,"<IMG src=\"%s-%d_%d.jpg\"><br>\n",fName->getCString(),pageNum,i);
+ GooString* fName;
+ for(int i = 0; i < HtmlOutputDev::imgList->getLength(); i++) {
+ fName= (GooString *)HtmlOutputDev::imgList->del(0);
+ fprintf(f,"<IMG src=\"%s\"><br>\n",fName->getCString());
+ delete fName;
+ }
HtmlOutputDev::imgNum=1;
- delete fName;
GooString* str;
- for(HtmlString *tmp=yxStrings;tmp;tmp=tmp->yxNext){
+ for(HtmlString *tmp=yxStrings;tmp;tmp=tmp->yxNext) {
if (tmp->htext){
str=new GooString(tmp->htext);
fputs(str->getCString(),f);
delete str;
fputs("<br>\n",f);
}
}
fputs("<hr>\n",f);
}
}
@@ -1189,7 +1197,7 @@
if (pgNum) delete pgNum;
if (imgnum) delete imgnum;
- if (fName) delete fName;
+ if (fName) imgList->append(fName);
}
else {
OutputDev::drawImageMask(state, ref, str, width, height, invert, inlineImg);
@@ -1274,13 +1282,119 @@
fclose(f1);
- delete fName;
+ if (fName) imgList->append(fName);
delete pgNum;
delete imgnum;
}
else {
+#ifdef ENABLE_LIBPNG
+ // Dump the image as a PNG file. Much of the PNG code
+ // comes from an example by Guillaume Cottenceau.
+ Guchar *p;
+ GfxRGB rgb;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_byte color_type= PNG_COLOR_TYPE_RGB;
+ png_byte bit_depth= 8;
+ png_byte *row = (png_byte *) malloc(3 * width); // 3 bytes/pixel: RGB
+ png_bytep *row_pointer= &row;
+
+ // Create the image filename
+ GooString *fName=new GooString(Docname);
+ fName->append("-");
+ GooString *pgNum= GooString::fromInt(pageNum);
+ GooString *imgnum= GooString::fromInt(imgNum);
+ fName->append(pgNum)->append("_")->append(imgnum)->append(".png");
+
+ // Open the image file
+ if (!(f1 = fopen(fName->getCString(), "wb"))) {
+ error(-1, "Couldn't open image file '%s'", fName->getCString());
+ return;
+ }
+
+ // Initialize the PNG stuff
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ error(-1, "png_create_write_struct failed");
+ return;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ error(-1, "png_create_info_struct failed");
+ return;
+ }
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ error(-1, "error during init_io");
+ return;
+ }
+
+ // Write the PNG header
+ png_init_io(png_ptr, f1);
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ error(-1, "error during writing png header");
+ return;
+ }
+
+ // Set up the type of PNG image and the compression level
+ png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
+
+ png_set_IHDR(png_ptr, info_ptr, width, height,
+ bit_depth, color_type, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ // Write the image info bytes
+ png_write_info(png_ptr, info_ptr);
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ error(-1, "error during writing png info bytes");
+ return;
+ }
+
+ // Initialize the image stream
+ ImageStream *imgStr = new ImageStream(str, width,
+ colorMap->getNumPixelComps(), colorMap->getBits());
+ imgStr->reset();
+
+ // For each line...
+ for (int y = 0; y < height; y++) {
+
+ // Convert into a PNG row
+ p = imgStr->getLine();
+ for (int x = 0; x < width; x++) {
+ colorMap->getRGB(p, &rgb);
+ // Write the RGB pixels into the row
+ row[3*x]= colToByte(rgb.r);
+ row[3*x+1]= colToByte(rgb.g);
+ row[3*x+2]= colToByte(rgb.b);
+ p += colorMap->getNumPixelComps();
+ }
+
+ // Write the row to the file
+ png_write_rows(png_ptr, row_pointer, 1);
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ error(-1, "error during png row write");
+ return;
+ }
+ }
+
+ // Finish off the PNG file
+ png_write_end(png_ptr, info_ptr);
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ error(-1, "error during png end of write");
+ return;
+ }
+
+ fclose(f1);
+ free(row);
+ imgList->append(fName);
+ ++imgNum;
+ delete pgNum;
+ delete imgnum;
+ delete imgStr;
+#else
OutputDev::drawImage(state, ref, str, width, height, colorMap,
- maskColors, inlineImg);
+ maskColors, inlineImg);
+#endif
}
}
More information about the poppler
mailing list