From b0c3b542446dba06069627258f90b8c004af8a93 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Fri, 1 Jan 2010 21:53:14 +1030 Subject: [PATCH] Make pdftoppm embed correct resolution in PNG files --- goo/ImgWriter.h | 2 +- goo/JpegWriter.cc | 5 ++++- goo/JpegWriter.h | 2 +- goo/PNGWriter.cc | 5 ++++- goo/PNGWriter.h | 3 ++- splash/SplashBitmap.cc | 8 ++++---- splash/SplashBitmap.h | 4 ++-- utils/HtmlOutputDev.cc | 3 ++- utils/pdftoppm.cc | 8 ++++---- 9 files changed, 24 insertions(+), 16 deletions(-) diff --git a/goo/ImgWriter.h b/goo/ImgWriter.h index 181620b..db3cfb4 100644 --- a/goo/ImgWriter.h +++ b/goo/ImgWriter.h @@ -19,7 +19,7 @@ class ImgWriter { public: virtual ~ImgWriter(); - virtual bool init(FILE *f, int width, int height) = 0; + virtual bool init(FILE *f, int width, int height, int hDPI, int vDPI) = 0; virtual bool writePointers(unsigned char **rowPointers, int rowCount) = 0; virtual bool writeRow(unsigned char **row) = 0; diff --git a/goo/JpegWriter.cc b/goo/JpegWriter.cc index 434febb..f4edfa6 100644 --- a/goo/JpegWriter.cc +++ b/goo/JpegWriter.cc @@ -35,7 +35,7 @@ JpegWriter::~JpegWriter() jpeg_destroy_compress(&cinfo); } -bool JpegWriter::init(FILE *f, int width, int height) +bool JpegWriter::init(FILE *f, int width, int height, int hDPI, int vDPI) { // Setup error handler cinfo.err = jpeg_std_error(&jerr); @@ -50,6 +50,9 @@ bool JpegWriter::init(FILE *f, int width, int height) // Set libjpeg configuration cinfo.image_width = width; cinfo.image_height = height; + cinfo.density_unit = 1; // dots per inch + cinfo.X_density = hDPI; + cinfo.Y_density = vDPI; cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ jpeg_set_defaults(&cinfo); diff --git a/goo/JpegWriter.h b/goo/JpegWriter.h index 9e4bf0c..c1d791e 100644 --- a/goo/JpegWriter.h +++ b/goo/JpegWriter.h @@ -25,7 +25,7 @@ class JpegWriter : public ImgWriter JpegWriter(); ~JpegWriter(); - bool init(FILE *f, int width, int height); + bool init(FILE *f, int width, int height, int hDPI, int vDPI); bool writePointers(unsigned char **rowPointers, int rowCount); bool writeRow(unsigned char **row); diff --git a/goo/PNGWriter.cc b/goo/PNGWriter.cc index 564d2fa..e534589 100644 --- a/goo/PNGWriter.cc +++ b/goo/PNGWriter.cc @@ -27,7 +27,7 @@ PNGWriter::~PNGWriter() png_destroy_write_struct(&png_ptr, &info_ptr); } -bool PNGWriter::init(FILE *f, int width, int height) +bool PNGWriter::init(FILE *f, int width, int height, int hDPI, int vDPI) { /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); @@ -63,6 +63,9 @@ bool PNGWriter::init(FILE *f, int width, int height) png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + // PNG_RESOLUTION_UNKNOWN means dots per inch + png_set_pHYs(png_ptr, info_ptr, hDPI, vDPI, PNG_RESOLUTION_UNKNOWN); + png_write_info(png_ptr, info_ptr); if (setjmp(png_jmpbuf(png_ptr))) { error(-1, "error during writing png info bytes"); diff --git a/goo/PNGWriter.h b/goo/PNGWriter.h index 97de86c..1a909e2 100644 --- a/goo/PNGWriter.h +++ b/goo/PNGWriter.h @@ -28,7 +28,7 @@ class PNGWriter : public ImgWriter PNGWriter(); ~PNGWriter(); - bool init(FILE *f, int width, int height); + bool init(FILE *f, int width, int height, int hDPI, int vDPI); bool writePointers(unsigned char **rowPointers, int rowCount); bool writeRow(unsigned char **row); @@ -38,6 +38,7 @@ class PNGWriter : public ImgWriter private: png_structp png_ptr; png_infop info_ptr; + int horiz_dpi, vert_dpi; }; #endif diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc index 999efd1..cf22c02 100644 --- a/splash/SplashBitmap.cc +++ b/splash/SplashBitmap.cc @@ -269,7 +269,7 @@ Guchar SplashBitmap::getAlpha(int x, int y) { return alpha[y * width + x]; } -SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, char *fileName) { +SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, char *fileName, int hDPI, int vDPI) { FILE *f; SplashError e; @@ -277,13 +277,13 @@ SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, char *fileN return splashErrOpenFile; } - e = writeImgFile(format, f); + e = writeImgFile(format, f, hDPI, vDPI); fclose(f); return e; } -SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f) { +SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI) { ImgWriter *writer; switch (format) { @@ -311,7 +311,7 @@ SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f) { return splashErrGeneric; } - if (!writer->init(f, width, height)) { + if (!writer->init(f, width, height, hDPI, vDPI)) { delete writer; return splashErrGeneric; } diff --git a/splash/SplashBitmap.h b/splash/SplashBitmap.h index de38445..fa1d30e 100644 --- a/splash/SplashBitmap.h +++ b/splash/SplashBitmap.h @@ -59,8 +59,8 @@ public: SplashError writePNMFile(char *fileName); SplashError writePNMFile(FILE *f); - SplashError writeImgFile(SplashImageFileFormat format, char *fileName); - SplashError writeImgFile(SplashImageFileFormat format, FILE *f); + SplashError writeImgFile(SplashImageFileFormat format, char *fileName, int hDPI, int vDPI); + SplashError writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI); void getPixel(int x, int y, SplashColorPtr pixel); Guchar getAlpha(int x, int y); diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index 89650dd..e654abb 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -1329,7 +1329,8 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, } PNGWriter *writer = new PNGWriter(); - if (!writer->init(f1, width, height)) { + // TODO can we calculate the resolution of the image? + if (!writer->init(f1, width, height, 72, 72)) { delete writer; fclose(f1); return; diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc index 2c4e869..74b71e0 100644 --- a/utils/pdftoppm.cc +++ b/utils/pdftoppm.cc @@ -162,17 +162,17 @@ static void savePageSlice(PDFDoc *doc, if (ppmFile != NULL) { if (png) { - bitmap->writeImgFile(splashFormatPng, ppmFile); + bitmap->writeImgFile(splashFormatPng, ppmFile, x_resolution, y_resolution); } else if (jpeg) { - bitmap->writeImgFile(splashFormatJpeg, ppmFile); + bitmap->writeImgFile(splashFormatJpeg, ppmFile, x_resolution, y_resolution); } else { bitmap->writePNMFile(ppmFile); } } else { if (png) { - bitmap->writeImgFile(splashFormatPng, stdout); + bitmap->writeImgFile(splashFormatPng, stdout, x_resolution, y_resolution); } else if (jpeg) { - bitmap->writeImgFile(splashFormatJpeg, stdout); + bitmap->writeImgFile(splashFormatJpeg, stdout, x_resolution, y_resolution); } else { bitmap->writePNMFile(stdout); } -- 1.6.3.3