[poppler] 9 commits - CMakeLists.txt goo/Makefile.am goo/NetPBMWriter.cc goo/NetPBMWriter.h goo/PNGWriter.cc goo/PNGWriter.h poppler/JBIG2Stream.h poppler/Stream.h utils/HtmlOutputDev.cc utils/ImageOutputDev.cc utils/ImageOutputDev.h utils/pdfimages.1 utils/pdfimages.cc utils/pdftocairo.cc

Albert Astals Cid aacid at kde.org
Sun Aug 25 15:25:42 PDT 2013


I think you copy/pasted the NetPBMWriter.* headears and there's too many names 
in them, no?

Cheers,
  Albert

El Diumenge, 25 d'agost de 2013, a les 15:12:53, Adrian Johnson va escriure:
>  CMakeLists.txt          |    1
>  goo/Makefile.am         |    2
>  goo/NetPBMWriter.cc     |   84 ++++++++
>  goo/NetPBMWriter.h      |   52 +++++
>  goo/PNGWriter.cc        |    4
>  goo/PNGWriter.h         |    2
>  poppler/JBIG2Stream.h   |    1
>  poppler/Stream.h        |    5
>  utils/HtmlOutputDev.cc  |   31 +--
>  utils/ImageOutputDev.cc |  463
> +++++++++++++++++++++++++++++++++--------------- utils/ImageOutputDev.h  | 
>  44 +++-
>  utils/pdfimages.1       |   84 +++++++-
>  utils/pdfimages.cc      |   44 ++++
>  utils/pdftocairo.cc     |    2
>  14 files changed, 640 insertions(+), 179 deletions(-)
> 
> New commits:
> commit af4f2b775946815b572622bf4c4d42ad3aea1141
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Sat Aug 24 21:25:51 2013 +0930
> 
>     pdfimages: Add -all option to write all image in their native format
> 
> diff --git a/utils/pdfimages.1 b/utils/pdfimages.1
> index 5a87573..a841ad7 100644
> --- a/utils/pdfimages.1
> +++ b/utils/pdfimages.1
> @@ -87,6 +87,10 @@ Encoding uses 0 for black and 1 for white
>  Input data fills from most significant bit to least significant bit.
>  .RE
>  .TP
> +.B \-all
> +Write JPEG, JPEG2000, JBIG2, and CCITT images in their native format. All
> other images are written as PNG files. +This is equivalent to specifying
> the options \-png \-j \-jp2 \-jbig2 \-ccitt. +.TP
>  .B \-list
>  Instead of writing the images, list the images along with various
> information for each image. Do not specify an .IR image-root
> diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc
> index 86ba3b7..ae05c8b 100644
> --- a/utils/pdfimages.cc
> +++ b/utils/pdfimages.cc
> @@ -56,6 +56,7 @@ static GBool dumpJPEG = gFalse;
>  static GBool dumpJP2 = gFalse;
>  static GBool dumpJBIG2 = gFalse;
>  static GBool dumpCCITT = gFalse;
> +static GBool allFormats = gFalse;
>  static GBool pageNames = gFalse;
>  static char ownerPassword[33] = "\001";
>  static char userPassword[33] = "\001";
> @@ -84,6 +85,8 @@ static const ArgDesc argDesc[] = {
>     "write JBIG2 images as JBIG2 files"},
>    {"-ccitt",      argFlag,     &dumpCCITT,      0,
>     "write CCITT images as CCITT files"},
> +  {"-all",      argFlag,     &allFormats,    0,
> +   "equivalent to -png -j -jp2 -jbig2 -ccitt"},
>    {"-list",   argFlag,     &listImages,      0,
>     "print list of images instead of saving"},
>    {"-opw",    argString,   ownerPassword,  sizeof(ownerPassword),
> @@ -189,12 +192,20 @@ int main(int argc, char *argv[]) {
>    // write image files
>    imgOut = new ImageOutputDev(imgRoot, pageNames, listImages);
>    if (imgOut->isOk()) {
> -    imgOut->enablePNG(enablePNG);
> -    imgOut->enableTiff(enableTiff);
> -    imgOut->enableJpeg(dumpJPEG);
> -    imgOut->enableJpeg2000(dumpJP2);
> -    imgOut->enableJBig2(dumpJBIG2);
> -    imgOut->enableCCITT(dumpCCITT);
> +    if (allFormats) {
> +      imgOut->enablePNG(gTrue);
> +      imgOut->enableJpeg(gTrue);
> +      imgOut->enableJpeg2000(gTrue);
> +      imgOut->enableJBig2(gTrue);
> +      imgOut->enableCCITT(gTrue);
> +    } else {
> +      imgOut->enablePNG(enablePNG);
> +      imgOut->enableTiff(enableTiff);
> +      imgOut->enableJpeg(dumpJPEG);
> +      imgOut->enableJpeg2000(dumpJP2);
> +      imgOut->enableJBig2(dumpJBIG2);
> +      imgOut->enableCCITT(dumpCCITT);
> +    }
>      doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0,
>                        gTrue, gFalse, gFalse);
>    }
> commit 25e96b6ddbbe54a75ddb97d2e235c1bd6033fe79
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Wed Aug 21 22:22:28 2013 +0930
> 
>     pdfimages: support ccitt output
> 
> diff --git a/poppler/Stream.h b/poppler/Stream.h
> index 9b40fd1..00b2925 100644
> --- a/poppler/Stream.h
> +++ b/poppler/Stream.h
> @@ -797,6 +797,11 @@ public:
> 
>    virtual void unfilteredReset ();
> 
> +  int getEncoding() { return encoding; }
> +  GBool getEndOfLine() { return endOfLine; }
> +  int getColumns() { return columns; }
> +  GBool getBlackIs1() { return black; }
> +
>  private:
> 
>    void ccittReset(GBool unfiltered);
> diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
> index ebdd644..ae7d309 100644
> --- a/utils/ImageOutputDev.cc
> +++ b/utils/ImageOutputDev.cc
> @@ -454,6 +454,41 @@ void ImageOutputDev::writeImage(GfxState *state, Object
> *ref, Stream *str, // dump JBIG2 embedded file
>      writeRawImage(str, "jb2e");
> 
> +  } else if (dumpCCITT && str->getKind() == strCCITTFax && !inlineImg) {
> +    // write CCITT parameters
> +    CCITTFaxStream *ccittStr = static_cast<CCITTFaxStream *>(str);
> +    FILE *f;
> +    setFilename("params");
> +    if (!(f = fopen(fileName, "wb"))) {
> +      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> +      return;
> +    }
> +    if (ccittStr->getEncoding() < 0)
> +      fprintf(f, "-4 ");
> +    else if (ccittStr->getEncoding() == 0)
> +      fprintf(f, "-1 ");
> +    else
> +      fprintf(f, "-2 ");
> +
> +    if (ccittStr->getEndOfLine())
> +      fprintf(f, "-A ");
> +    else
> +      fprintf(f, "-P ");
> +
> +    fprintf(f, "-X %d ", ccittStr->getColumns());
> +
> +    if (ccittStr->getBlackIs1())
> +      fprintf(f, "-W ");
> +    else
> +      fprintf(f, "-B ");
> +
> +    fprintf(f, "-M\n"); // PDF uses MSB first
> +
> +    fclose(f);
> +
> +    // dump CCITT file
> +    writeRawImage(str, "ccitt");
> +
>    } else if (outputPNG) {
>      // output in PNG format
> 
> diff --git a/utils/ImageOutputDev.h b/utils/ImageOutputDev.h
> index 75063a2..8d0785c 100644
> --- a/utils/ImageOutputDev.h
> +++ b/utils/ImageOutputDev.h
> @@ -85,6 +85,9 @@ public:
>    // Use JBIG2 format for JBIG2 files
>    void enableJBig2(GBool jbig2) { dumpJBIG2 = jbig2; }
> 
> +  // Use CCITT format for CCITT files
> +  void enableCCITT(GBool ccitt) { dumpCCITT = ccitt; }
> +
>    // Check if file was successfully created.
>    virtual GBool isOk() { return ok; }
> 
> @@ -162,6 +165,7 @@ private:
>    GBool dumpJPEG;		// set to dump native JPEG files
>    GBool dumpJP2;		// set to dump native JPEG2000 files
>    GBool dumpJBIG2;		// set to dump native JBIG2 files
> +  GBool dumpCCITT;		// set to dump native CCITT files
>    GBool outputPNG;		// set to output in PNG format
>    GBool outputTiff;		// set to output in TIFF format
>    GBool pageNames;		// set to include page number in file names
> diff --git a/utils/pdfimages.1 b/utils/pdfimages.1
> index 23530c5..5a87573 100644
> --- a/utils/pdfimages.1
> +++ b/utils/pdfimages.1
> @@ -50,12 +50,49 @@ Write images in JPEG2000 format as JP2 files instead of
> the default format. The .B \-jbig2
>  Write images in JBIG2 format as JBIG2 files instead of the default format.
> JBIG2 data in PDF is of the embedded type. The embedded type of JBIG2 has
> an optional separate file containing global data. The embedded data is
> written with the extension .jb2e and the global data (if available) will be
> written to the same image number with the extension .jb2g. The content of
> both these files is indentical to the JBIG2 data in the PDF. .TP
> +.B \-ccitt
> +Write images in CCITT format as CCITT files instead of the default
> +format. The CCITT file is identical to the JPEG2000 data stored in the
> +PDF. PDF files contain additional parameters specifying
> +how to decode the CCITT data. These parameters are translated to
> +fax2tiff input options and written to a .params file with the same image
> +number. The parameters are:
> +.RS
> +.TP
> +.B \-1
> +1D Group 3 encoding
> +.TP
> +.B \-2
> +2D Group 3 encoding
> +.TP
> +.B \-4
> +Group 4 encoding
> +.TP
> +.B \-A
> +Beginning of line is aligned on a byte boundary
> +.TP
> +.B \-P
> +Beginning of line is not aligned on a byte boundary
> +.TP
> +.B \-X n
> +The image width in pixels
> +.TP
> +.B \-W
> +Encoding uses 1 for black and 0 for white
> +.TP
> +.B \-B
> +Encoding uses 0 for black and 1 for white
> +.TP
> +.B \-M
> +Input data fills from most significant bit to least significant bit.
> +.RE
> +.TP
>  .B \-list
>  Instead of writing the images, list the images along with various
> information for each image. Do not specify an .IR image-root
>  with this option.
>  .IP
> -The following information is listed for each font:
> +The following information is listed for each image:
>  .RS
>  .TP
>  .B page
> diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc
> index 48d12c4..86ba3b7 100644
> --- a/utils/pdfimages.cc
> +++ b/utils/pdfimages.cc
> @@ -55,6 +55,7 @@ static GBool enableTiff = gFalse;
>  static GBool dumpJPEG = gFalse;
>  static GBool dumpJP2 = gFalse;
>  static GBool dumpJBIG2 = gFalse;
> +static GBool dumpCCITT = gFalse;
>  static GBool pageNames = gFalse;
>  static char ownerPassword[33] = "\001";
>  static char userPassword[33] = "\001";
> @@ -81,6 +82,8 @@ static const ArgDesc argDesc[] = {
>     "write JPEG2000 images as JP2 files"},
>    {"-jbig2",      argFlag,     &dumpJBIG2,      0,
>     "write JBIG2 images as JBIG2 files"},
> +  {"-ccitt",      argFlag,     &dumpCCITT,      0,
> +   "write CCITT images as CCITT files"},
>    {"-list",   argFlag,     &listImages,      0,
>     "print list of images instead of saving"},
>    {"-opw",    argString,   ownerPassword,  sizeof(ownerPassword),
> @@ -191,6 +194,7 @@ int main(int argc, char *argv[]) {
>      imgOut->enableJpeg(dumpJPEG);
>      imgOut->enableJpeg2000(dumpJP2);
>      imgOut->enableJBig2(dumpJBIG2);
> +    imgOut->enableCCITT(dumpCCITT);
>      doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0,
>                        gTrue, gFalse, gFalse);
>    }
> commit 086413263cb63a24d9492fbe534fdcc34b45951a
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Sun Aug 18 20:37:01 2013 +0930
> 
>     pdfimages: support JBIG2 output
> 
> diff --git a/poppler/JBIG2Stream.h b/poppler/JBIG2Stream.h
> index be1b3bd..0ee2518 100644
> --- a/poppler/JBIG2Stream.h
> +++ b/poppler/JBIG2Stream.h
> @@ -56,6 +56,7 @@ public:
>    virtual int lookChar();
>    virtual GooString *getPSFilter(int psLevel, const char *indent);
>    virtual GBool isBinary(GBool last = gTrue);
> +  virtual Object *getGlobalsStream() { return &globalsStream; }
> 
>  private:
>    virtual GBool hasGetChars() { return true; }
> diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
> index b92acaa..ebdd644 100644
> --- a/utils/ImageOutputDev.cc
> +++ b/utils/ImageOutputDev.cc
> @@ -48,6 +48,7 @@
>  #include "GfxState.h"
>  #include "Object.h"
>  #include "Stream.h"
> +#include "JBIG2Stream.h"
>  #include "ImageOutputDev.h"
> 
>  ImageOutputDev::ImageOutputDev(char *fileRootA, GBool pageNamesA, GBool
> listImagesA) { @@ -429,6 +430,30 @@ void
> ImageOutputDev::writeImage(GfxState *state, Object *ref, Stream *str, //
> dump JPEG2000 file
>      writeRawImage(str, "jp2");
> 
> +  } else if (dumpJBIG2 && str->getKind() == strJBIG2 && !inlineImg) {
> +    // dump JBIG2 globals stream if available
> +    JBIG2Stream *jb2Str = static_cast<JBIG2Stream *>(str);
> +    Object *globals = jb2Str->getGlobalsStream();
> +    if (globals->isStream()) {
> +      FILE *f;
> +      int c;
> +      Stream *str = globals->getStream();
> +
> +      setFilename("jb2g");
> +      if (!(f = fopen(fileName, "wb"))) {
> +        error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> +        return;
> +      }
> +      str->reset();
> +      while ((c = str->getChar()) != EOF)
> +        fputc(c, f);
> +      str->close();
> +      fclose(f);
> +    }
> +
> +    // dump JBIG2 embedded file
> +    writeRawImage(str, "jb2e");
> +
>    } else if (outputPNG) {
>      // output in PNG format
> 
> diff --git a/utils/ImageOutputDev.h b/utils/ImageOutputDev.h
> index b674f05..75063a2 100644
> --- a/utils/ImageOutputDev.h
> +++ b/utils/ImageOutputDev.h
> @@ -82,6 +82,9 @@ public:
>    // Use Jpeg2000 format for Jpeg2000 files
>    void enableJpeg2000(GBool jp2) { dumpJP2 = jp2; }
> 
> +  // Use JBIG2 format for JBIG2 files
> +  void enableJBig2(GBool jbig2) { dumpJBIG2 = jbig2; }
> +
>    // Check if file was successfully created.
>    virtual GBool isOk() { return ok; }
> 
> @@ -158,6 +161,7 @@ private:
>    GBool listImages;		// list images instead of dumping
>    GBool dumpJPEG;		// set to dump native JPEG files
>    GBool dumpJP2;		// set to dump native JPEG2000 files
> +  GBool dumpJBIG2;		// set to dump native JBIG2 files
>    GBool outputPNG;		// set to output in PNG format
>    GBool outputTiff;		// set to output in TIFF format
>    GBool pageNames;		// set to include page number in file names
> diff --git a/utils/pdfimages.1 b/utils/pdfimages.1
> index 79b3aad..23530c5 100644
> --- a/utils/pdfimages.1
> +++ b/utils/pdfimages.1
> @@ -11,7 +11,7 @@ pdfimages \- Portable Document Format (PDF) image
> extractor .B Pdfimages
>  saves images from a Portable Document Format (PDF) file as Portable
>  Pixmap (PPM), Portable Bitmap (PBM), Portable Network Graphics (PNG),
> -Tagged Image File Format (TIFF), JPEG, or JPEG2000 files.
> +Tagged Image File Format (TIFF), JPEG, JPEG2000, or JBIG2 files.
>  .PP
>  Pdfimages reads the PDF file
>  .IR PDF-file ,
> @@ -21,12 +21,12 @@ where
>  .I nnn
>  is the image number and
>  .I xxx
> -is the image type (.ppm, .pbm, .png, .tif, .jpg, or jp2).
> +is the image type (.ppm, .pbm, .png, .tif, .jpg, jp2, jb2e, or jb2g).
>  .PP
>  The default output format is PBM (for monochrome images) or PPM for
> non-monochrome. The -\-png or \-tiff options change to default output to
> PNG or TIFF respectively. In addition the \-j and -\-jp2 options will cause
> JPEG and JPEG2000, respectively, images in the PDF file to be written in
> their -native format.
> +\-png or \-tiff options change to default output to PNG or TIFF
> respectively. In addition the \-j, +\-jp2, and \-jbig2 options will cause
> JPEG, JPEG2000, and JBIG2, respectively, images in the PDF file +to be
> written in their native format.
>  .SH OPTIONS
>  .TP
>  .BI \-f " number"
> @@ -47,6 +47,9 @@ Write images in JPEG format as JPEG files instead of the
> default format. The JPE .B \-jp2
>  Write images in JPEG2000 format as JP2 files instead of the default format.
> The JP2 file is identical to the JPEG2000 data stored in the PDF. .TP
> +.B \-jbig2
> +Write images in JBIG2 format as JBIG2 files instead of the default format.
> JBIG2 data in PDF is of the embedded type. The embedded type of JBIG2 has
> an optional separate file containing global data. The embedded data is
> written with the extension .jb2e and the global data (if available) will be
> written to the same image number with the extension .jb2g. The content of
> both these files is indentical to the JBIG2 data in the PDF. +.TP
>  .B \-list
>  Instead of writing the images, list the images along with various
> information for each image. Do not specify an .IR image-root
> diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc
> index 0d2a420..48d12c4 100644
> --- a/utils/pdfimages.cc
> +++ b/utils/pdfimages.cc
> @@ -54,6 +54,7 @@ static GBool enablePNG = gFalse;
>  static GBool enableTiff = gFalse;
>  static GBool dumpJPEG = gFalse;
>  static GBool dumpJP2 = gFalse;
> +static GBool dumpJBIG2 = gFalse;
>  static GBool pageNames = gFalse;
>  static char ownerPassword[33] = "\001";
>  static char userPassword[33] = "\001";
> @@ -78,6 +79,8 @@ static const ArgDesc argDesc[] = {
>     "write JPEG images as JPEG files"},
>    {"-jp2",      argFlag,     &dumpJP2,      0,
>     "write JPEG2000 images as JP2 files"},
> +  {"-jbig2",      argFlag,     &dumpJBIG2,      0,
> +   "write JBIG2 images as JBIG2 files"},
>    {"-list",   argFlag,     &listImages,      0,
>     "print list of images instead of saving"},
>    {"-opw",    argString,   ownerPassword,  sizeof(ownerPassword),
> @@ -187,6 +190,7 @@ int main(int argc, char *argv[]) {
>      imgOut->enableTiff(enableTiff);
>      imgOut->enableJpeg(dumpJPEG);
>      imgOut->enableJpeg2000(dumpJP2);
> +    imgOut->enableJBig2(dumpJBIG2);
>      doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0,
>                        gTrue, gFalse, gFalse);
>    }
> commit 2845ebabd00a2755549b8db436e78a3e0e0c0713
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Sun Aug 18 20:07:31 2013 +0930
> 
>     pdfimages: add support for writing JPEG2000 files
> 
> diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
> index aef3f65..b92acaa 100644
> --- a/utils/ImageOutputDev.cc
> +++ b/utils/ImageOutputDev.cc
> @@ -425,6 +425,10 @@ void ImageOutputDev::writeImage(GfxState *state, Object
> *ref, Stream *str, // dump JPEG file
>      writeRawImage(str, "jpg");
> 
> +  } else if (dumpJP2 && str->getKind() == strJPX && !inlineImg) {
> +    // dump JPEG2000 file
> +    writeRawImage(str, "jp2");
> +
>    } else if (outputPNG) {
>      // output in PNG format
> 
> diff --git a/utils/ImageOutputDev.h b/utils/ImageOutputDev.h
> index a3d18f7..b674f05 100644
> --- a/utils/ImageOutputDev.h
> +++ b/utils/ImageOutputDev.h
> @@ -79,6 +79,9 @@ public:
>    // Use Jpeg format for Jpeg files
>    void enableJpeg(GBool jpeg) { dumpJPEG = jpeg; }
> 
> +  // Use Jpeg2000 format for Jpeg2000 files
> +  void enableJpeg2000(GBool jp2) { dumpJP2 = jp2; }
> +
>    // Check if file was successfully created.
>    virtual GBool isOk() { return ok; }
> 
> @@ -154,6 +157,7 @@ private:
>    char *fileName;		// buffer for output file names
>    GBool listImages;		// list images instead of dumping
>    GBool dumpJPEG;		// set to dump native JPEG files
> +  GBool dumpJP2;		// set to dump native JPEG2000 files
>    GBool outputPNG;		// set to output in PNG format
>    GBool outputTiff;		// set to output in TIFF format
>    GBool pageNames;		// set to include page number in file names
> diff --git a/utils/pdfimages.1 b/utils/pdfimages.1
> index 5b07c5c..79b3aad 100644
> --- a/utils/pdfimages.1
> +++ b/utils/pdfimages.1
> @@ -11,7 +11,7 @@ pdfimages \- Portable Document Format (PDF) image
> extractor .B Pdfimages
>  saves images from a Portable Document Format (PDF) file as Portable
>  Pixmap (PPM), Portable Bitmap (PBM), Portable Network Graphics (PNG),
> -Tagged Image File Format (TIFF), or JPEG files.
> +Tagged Image File Format (TIFF), JPEG, or JPEG2000 files.
>  .PP
>  Pdfimages reads the PDF file
>  .IR PDF-file ,
> @@ -21,11 +21,12 @@ where
>  .I nnn
>  is the image number and
>  .I xxx
> -is the image type (.ppm, .pbm, .png, .tif, or .jpg).
> +is the image type (.ppm, .pbm, .png, .tif, .jpg, or jp2).
>  .PP
>  The default output format is PBM (for monochrome images) or PPM for
> non-monochrome. The -\-png or \-tiff options change to default output to
> PNG or TIFF respectively. In addition the \-j option -will cause JPEG
> images in the PDF file to be written in JPEG format. +\-png or \-tiff
> options change to default output to PNG or TIFF respectively. In addition
> the \-j and +\-jp2 options will cause JPEG and JPEG2000, respectively,
> images in the PDF file to be written in their +native format.
>  .SH OPTIONS
>  .TP
>  .BI \-f " number"
> @@ -43,6 +44,9 @@ Change the default output format to TIFF.
>  .B \-j
>  Write images in JPEG format as JPEG files instead of the default format.
> The JPEG file is identical to the JPEG data stored in the PDF. .TP
> +.B \-jp2
> +Write images in JPEG2000 format as JP2 files instead of the default format.
> The JP2 file is identical to the JPEG2000 data stored in the PDF. +.TP
>  .B \-list
>  Instead of writing the images, list the images along with various
> information for each image. Do not specify an .IR image-root
> diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc
> index fee7b75..0d2a420 100644
> --- a/utils/pdfimages.cc
> +++ b/utils/pdfimages.cc
> @@ -53,6 +53,7 @@ static GBool listImages = gFalse;
>  static GBool enablePNG = gFalse;
>  static GBool enableTiff = gFalse;
>  static GBool dumpJPEG = gFalse;
> +static GBool dumpJP2 = gFalse;
>  static GBool pageNames = gFalse;
>  static char ownerPassword[33] = "\001";
>  static char userPassword[33] = "\001";
> @@ -75,6 +76,8 @@ static const ArgDesc argDesc[] = {
>  #endif
>    {"-j",      argFlag,     &dumpJPEG,      0,
>     "write JPEG images as JPEG files"},
> +  {"-jp2",      argFlag,     &dumpJP2,      0,
> +   "write JPEG2000 images as JP2 files"},
>    {"-list",   argFlag,     &listImages,      0,
>     "print list of images instead of saving"},
>    {"-opw",    argString,   ownerPassword,  sizeof(ownerPassword),
> @@ -183,6 +186,7 @@ int main(int argc, char *argv[]) {
>      imgOut->enablePNG(enablePNG);
>      imgOut->enableTiff(enableTiff);
>      imgOut->enableJpeg(dumpJPEG);
> +    imgOut->enableJpeg2000(dumpJP2);
>      doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0,
>                        gTrue, gFalse, gFalse);
>    }
> commit 2021c8ffcb36432049c4305e85ced2ae139086f3
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Sun Aug 18 17:29:00 2013 +0930
> 
>     pdfimages: add support for png and tiff output
> 
> diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
> index 110ba21..aef3f65 100644
> --- a/utils/ImageOutputDev.cc
> +++ b/utils/ImageOutputDev.cc
> @@ -42,19 +42,23 @@
>  #include <math.h>
>  #include "goo/gmem.h"
>  #include "goo/NetPBMWriter.h"
> +#include "goo/PNGWriter.h"
> +#include "goo/TiffWriter.h"
>  #include "Error.h"
>  #include "GfxState.h"
>  #include "Object.h"
>  #include "Stream.h"
>  #include "ImageOutputDev.h"
> 
> -ImageOutputDev::ImageOutputDev(char *fileRootA, GBool pageNamesA, GBool
> dumpJPEGA, GBool listImagesA) { +ImageOutputDev::ImageOutputDev(char
> *fileRootA, GBool pageNamesA, GBool listImagesA) { listImages =
> listImagesA;
>    if (!listImages) {
>      fileRoot = copyString(fileRootA);
>      fileName = (char *)gmalloc(strlen(fileRoot) + 45);
>    }
> -  dumpJPEG = dumpJPEGA;
> +  outputPNG = gFalse;
> +  outputTiff = gFalse;
> +  dumpJPEG =  gFalse;
>    pageNames = pageNamesA;
>    imgNum = 0;
>    pageNum = 0;
> @@ -374,6 +378,21 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer,
> ImageFormat format, const writer->writeRow(&row);
>        break;
> 
> +    case imgGray:
> +      p = imgStr->getLine();
> +      rowp = row;
> +      for (int x = 0; x < width; ++x) {
> +        if (p) {
> +          colorMap->getGray(p, &gray);
> +          *rowp++ = colToByte(gray);
> +          p += colorMap->getNumPixelComps();
> +        } else {
> +          *rowp++ = 0;
> +        }
> +      }
> +      writer->writeRow(&row);
> +      break;
> +
>      case imgMonochrome:
>        int size = (width + 7)/8;
>        for (int x = 0; x < size; x++)
> @@ -406,10 +425,52 @@ void ImageOutputDev::writeImage(GfxState *state,
> Object *ref, Stream *str, // dump JPEG file
>      writeRawImage(str, "jpg");
> 
> +  } else if (outputPNG) {
> +    // output in PNG format
> +
> +#if ENABLE_LIBPNG
> +    ImgWriter *writer;
> +
> +    if (!colorMap || (colorMap->getNumPixelComps() == 1 &&
> colorMap->getBits() == 1)) { +      writer = new
> PNGWriter(PNGWriter::MONOCHROME);
> +      format = imgMonochrome;
> +    } else if (colorMap->getColorSpace()->getMode() == csDeviceGray ||
> +               colorMap->getColorSpace()->getMode() == csCalGray) {
> +      writer = new PNGWriter(PNGWriter::GRAY);
> +      format = imgGray;
> +    } else {
> +      writer = new PNGWriter(PNGWriter::RGB);
> +      format = imgRGB;
> +    }
> +
> +    writeImageFile(writer, format, "png", str, width, height, colorMap);
> +#endif
> +
> +  } else if (outputTiff) {
> +    // output in TIFF format
> +
> +#if ENABLE_LIBTIFF
> +    ImgWriter *writer;
> +
> +    if (!colorMap || (colorMap->getNumPixelComps() == 1 &&
> colorMap->getBits() == 1)) { +      writer = new
> TiffWriter(TiffWriter::MONOCHROME);
> +      format = imgMonochrome;
> +    } else if (colorMap->getColorSpace()->getMode() == csDeviceGray ||
> +               colorMap->getColorSpace()->getMode() == csCalGray) {
> +      writer = new TiffWriter(TiffWriter::GRAY);
> +      format = imgGray;
> +    } else {
> +      writer = new TiffWriter(TiffWriter::RGB);
> +      format = imgRGB;
> +    }
> +
> +    writeImageFile(writer, format, "tif", str, width, height, colorMap);
> +#endif
> +
>    } else {
> +    // output in PPM/PBM format
>      ImgWriter *writer;
> 
> -    // dump PBM file
>      if (!colorMap || (colorMap->getNumPixelComps() == 1 &&
> colorMap->getBits() == 1)) { writer = new
> NetPBMWriter(NetPBMWriter::MONOCHROME);
>        format = imgMonochrome;
> diff --git a/utils/ImageOutputDev.h b/utils/ImageOutputDev.h
> index d89836f..a3d18f7 100644
> --- a/utils/ImageOutputDev.h
> +++ b/utils/ImageOutputDev.h
> @@ -55,19 +55,30 @@ public:
>    };
>    enum ImageFormat {
>      imgRGB,
> +    imgGray,
>      imgMonochrome
>    };
> 
>    // Create an OutputDev which will write images to files named
>    // <fileRoot>-NNN.<type> or <fileRoot>-PPP-NNN.<type>, if
>    // <pageNames> is set. Normally, all images are written as PBM
> -  // (.pbm) or PPM (.ppm) files.  If <dumpJPEG> is set, JPEG images
> +  // (.pbm) or PPM (.ppm) files unless PNG or Tiff output is enabled
> +  // (PNG is used if both are enabled).  If Jpeg is enabled, JPEG images
>    // are written as JPEG (.jpg) files.
> -  ImageOutputDev(char *fileRootA, GBool pageNamesA, GBool dumpJPEGA, GBool
> listImagesA); +  ImageOutputDev(char *fileRootA, GBool pageNamesA, GBool
> listImagesA);
> 
>    // Destructor.
>    virtual ~ImageOutputDev();
> 
> +  // Use PNG format for output
> +  void enablePNG(GBool png) { outputPNG = png; }
> +
> +  // Use TIFF format for output
> +  void enableTiff(GBool tiff) { outputTiff = tiff; }
> +
> +  // Use Jpeg format for Jpeg files
> +  void enableJpeg(GBool jpeg) { dumpJPEG = jpeg; }
> +
>    // Check if file was successfully created.
>    virtual GBool isOk() { return ok; }
> 
> @@ -143,6 +154,8 @@ private:
>    char *fileName;		// buffer for output file names
>    GBool listImages;		// list images instead of dumping
>    GBool dumpJPEG;		// set to dump native JPEG files
> +  GBool outputPNG;		// set to output in PNG format
> +  GBool outputTiff;		// set to output in TIFF format
>    GBool pageNames;		// set to include page number in file names
>    int pageNum;			// current page number
>    int imgNum;			// current image number
> diff --git a/utils/pdfimages.1 b/utils/pdfimages.1
> index e98bf29..5b07c5c 100644
> --- a/utils/pdfimages.1
> +++ b/utils/pdfimages.1
> @@ -10,17 +10,22 @@ pdfimages \- Portable Document Format (PDF) image
> extractor .SH DESCRIPTION
>  .B Pdfimages
>  saves images from a Portable Document Format (PDF) file as Portable
> -Pixmap (PPM), Portable Bitmap (PBM), or JPEG files.
> +Pixmap (PPM), Portable Bitmap (PBM), Portable Network Graphics (PNG),
> +Tagged Image File Format (TIFF), or JPEG files.
>  .PP
>  Pdfimages reads the PDF file
>  .IR PDF-file ,
> -scans one or more pages, and writes one PPM, PBM, or JPEG file for each
> image, +scans one or more pages, and writes one file for each image,
>  .IR image-root - nnn . xxx ,
>  where
>  .I nnn
>  is the image number and
>  .I xxx
> -is the image type (.ppm, .pbm, .jpg).
> +is the image type (.ppm, .pbm, .png, .tif, or .jpg).
> +.PP
> +The default output format is PBM (for monochrome images) or PPM for
> non-monochrome. The +\-png or \-tiff options change to default output to
> PNG or TIFF respectively. In addition the \-j option +will cause JPEG
> images in the PDF file to be written in JPEG format. .SH OPTIONS
>  .TP
>  .BI \-f " number"
> @@ -29,11 +34,14 @@ Specifies the first page to scan.
>  .BI \-l " number"
>  Specifies the last page to scan.
>  .TP
> +.B \-png
> +Change the default output format to PNG.
> +.TP
> +.B \-tiff
> +Change the default output format to TIFF.
> +.TP
>  .B \-j
> -Normally, all images are written as PBM (for monochrome images) or PPM
> -(for non-monochrome images) files.  With this option, images in DCT
> -format are saved as JPEG files.  All non-DCT images are saved in
> -PBM/PPM format as usual.
> +Write images in JPEG format as JPEG files instead of the default format.
> The JPEG file is identical to the JPEG data stored in the PDF. .TP
>  .B \-list
>  Instead of writing the images, list the images along with various
> information for each image. Do not specify an diff --git
> a/utils/pdfimages.cc b/utils/pdfimages.cc
> index 7b6cad0..fee7b75 100644
> --- a/utils/pdfimages.cc
> +++ b/utils/pdfimages.cc
> @@ -50,6 +50,8 @@
>  static int firstPage = 1;
>  static int lastPage = 0;
>  static GBool listImages = gFalse;
> +static GBool enablePNG = gFalse;
> +static GBool enableTiff = gFalse;
>  static GBool dumpJPEG = gFalse;
>  static GBool pageNames = gFalse;
>  static char ownerPassword[33] = "\001";
> @@ -63,6 +65,14 @@ static const ArgDesc argDesc[] = {
>     "first page to convert"},
>    {"-l",      argInt,      &lastPage,      0,
>     "last page to convert"},
> +#if ENABLE_LIBPNG
> +  {"-png",      argFlag,     &enablePNG,      0,
> +   "change the default output format to PNG"},
> +#endif
> +#if ENABLE_LIBTIFF
> +  {"-tiff",      argFlag,     &enableTiff,      0,
> +   "change the default output format to TIFF"},
> +#endif
>    {"-j",      argFlag,     &dumpJPEG,      0,
>     "write JPEG images as JPEG files"},
>    {"-list",   argFlag,     &listImages,      0,
> @@ -168,10 +178,13 @@ int main(int argc, char *argv[]) {
>      lastPage = doc->getNumPages();
> 
>    // write image files
> -  imgOut = new ImageOutputDev(imgRoot, pageNames, dumpJPEG, listImages);
> +  imgOut = new ImageOutputDev(imgRoot, pageNames, listImages);
>    if (imgOut->isOk()) {
> -      doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0,
> -			gTrue, gFalse, gFalse);
> +    imgOut->enablePNG(enablePNG);
> +    imgOut->enableTiff(enableTiff);
> +    imgOut->enableJpeg(dumpJPEG);
> +    doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0,
> +                      gTrue, gFalse, gFalse);
>    }
>    delete imgOut;
> 
> commit 8f466775c77b09a7114c688004317e6db05bcd3f
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Sun Aug 18 16:08:02 2013 +0930
> 
>     Change PNGWriter monochrome format to be 8 pixels/byte
> 
>     to be consistent with TiffWriter and NetPBMWriter
> 
> diff --git a/goo/PNGWriter.cc b/goo/PNGWriter.cc
> index b775600..4370f28 100644
> --- a/goo/PNGWriter.cc
> +++ b/goo/PNGWriter.cc
> @@ -147,10 +147,6 @@ bool PNGWriter::init(FILE *f, int width, int height,
> int hDPI, int vDPI) return false;
>    }
> 
> -  // pack 1 pixel/byte rows into 8 pixels/byte
> -  if (priv->format == MONOCHROME)
> -    png_set_packing(priv->png_ptr);
> -
>    return true;
>  }
> 
> diff --git a/goo/PNGWriter.h b/goo/PNGWriter.h
> index ac8f95a..64b8833 100644
> --- a/goo/PNGWriter.h
> +++ b/goo/PNGWriter.h
> @@ -31,7 +31,7 @@ public:
>    /* RGB        - 3 bytes/pixel
>     * RGBA       - 4 bytes/pixel
>     * GRAY       - 1 byte/pixel
> -   * MONOCHROME - 1 byte/pixel. PNGWriter will bitpack to 8 pixels/byte
> +   * MONOCHROME - 8 pixels/byte
>     */
>    enum Format { RGB, RGBA, GRAY, MONOCHROME };
> 
> diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
> index 7926674..3926178 100644
> --- a/utils/HtmlOutputDev.cc
> +++ b/utils/HtmlOutputDev.cc
> @@ -1413,32 +1413,39 @@ void HtmlOutputDev::drawPngImage(GfxState *state,
> Stream *str, int width, int he delete imgStr;
>    }
>    else { // isMask == true
> -    ImageStream *imgStr = new ImageStream(str, width, 1, 1);
> -    imgStr->reset();
> +    int size = (width + 7)/8;
> +
> +    // PDF masks use 0 = draw current color, 1 = leave unchanged.
> +    // We invert this to provide the standard interpretation of alpha
> +    // (0 = transparent, 1 = opaque). If the colorMap already inverts
> +    // the mask we leave the data unchanged.
> +    int invert_bits = 0xff;
> +    if (colorMap) {
> +      GfxGray gray;
> +      Guchar zero = 0;
> +      colorMap->getGray(&zero, &gray);
> +      if (colToByte(gray) == 0)
> +        invert_bits = 0x00;
> +    }
> 
> -    Guchar *png_row = (Guchar *)gmalloc( width );
> +    str->reset();
> +    Guchar *png_row = (Guchar *)gmalloc(size);
> 
>      for (int ri = 0; ri < height; ++ri)
>      {
> -      // read the row of the mask
> -      Guchar *bit_row = imgStr->getLine();
> -
> -      // invert for PNG
> -      for(int i = 0; i < width; i++)
> -        png_row[i] = bit_row[i] ? 0xff : 0x00;
> +      for(int i = 0; i < size; i++)
> +        png_row[i] = str->getChar() ^ invert_bits;
> 
>        if (!writer->writeRow( &png_row ))
>        {
>          error(errIO, -1, "Failed to write into PNG '%s'",
> fName->getCString()); delete writer;
>          fclose(f1);
> -        delete imgStr;
>          gfree(png_row);
>          return;
>        }
>      }
> -    imgStr->close();
> -    delete imgStr;
> +    str->close();
>      gfree(png_row);
>    }
> 
> diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
> index 58f3cd8..110ba21 100644
> --- a/utils/ImageOutputDev.cc
> +++ b/utils/ImageOutputDev.cc
> @@ -315,7 +315,7 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer,
> ImageFormat format, const GfxRGB rgb;
>    GfxGray gray;
>    Guchar zero = 0;
> -  int invert_bits = 0xff;
> +  int invert_bits;
> 
>    setFilename(ext);
>    ++imgNum;
> @@ -341,8 +341,11 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer,
> ImageFormat format, const
> 
>    row = (unsigned char *) gmallocn(width, sizeof(unsigned int));
> 
> -  // if 0 comes out as 0 in the color map, the we _flip_ stream bits
> -  // otherwise we pass through stream bits unmolested
> +  // PDF masks use 0 = draw current color, 1 = leave unchanged.
> +  // We invert this to provide the standard interpretation of alpha
> +  // (0 = transparent, 1 = opaque). If the colorMap already inverts
> +  // the mask we leave the data unchanged.
> +  invert_bits = 0xff;
>    if (colorMap) {
>      colorMap->getGray(&zero, &gray);
>      if (colToByte(gray) == 0)
> diff --git a/utils/pdftocairo.cc b/utils/pdftocairo.cc
> index 192d295..841c388 100644
> --- a/utils/pdftocairo.cc
> +++ b/utils/pdftocairo.cc
> @@ -370,7 +370,7 @@ void writePageImage(GooString *filename)
>  	int b = (*pixel & 0x000000ff) >>  0;
>  	// an arbitrary integer approximation of .3*r + .59*g + .11*b
>  	int y = (r*19661+g*38666+b*7209 + 32829)>>16;
> -        if (tiff && mono) {
> +        if (mono) {
>            if (bit == 7)
>              *rowp = 0;
>            if (y > 127)
> commit e53aec2c61ba42cf0635dc05f8e27e3503c1eaac
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Sun Aug 18 15:50:39 2013 +0930
> 
>     Refactor ImageOutputDev to facilitate adding more output formats
> 
>     - Move PPM/PBM code into a NetPBMWriter class so PNGWriter and
>       TiffWritersupport be added.
> 
>     - Create generic WriteRawIMage function for writing jpeg files so
>       support for jpeg2000/jbig2 can be added.
> 
> diff --git a/CMakeLists.txt b/CMakeLists.txt
> index 0da8c6d..1e03c5d 100644
> --- a/CMakeLists.txt
> +++ b/CMakeLists.txt
> @@ -264,6 +264,7 @@ set(poppler_SRCS
>    goo/GooString.cc
>    goo/gmem.cc
>    goo/FixedPoint.cc
> +  goo/NetPBMWriter.cc
>    goo/PNGWriter.cc
>    goo/TiffWriter.cc
>    goo/JpegWriter.cc
> diff --git a/goo/Makefile.am b/goo/Makefile.am
> index 0764e79..a48b20e 100644
> --- a/goo/Makefile.am
> +++ b/goo/Makefile.am
> @@ -13,6 +13,7 @@ poppler_goo_include_HEADERS =			\
>  	gmem.h					\
>  	gfile.h					\
>  	FixedPoint.h				\
> +	NetPBMWriter.h				\
>  	PNGWriter.h				\
>  	JpegWriter.h				\
>  	TiffWriter.h				\
> @@ -55,6 +56,7 @@ libgoo_la_SOURCES =				\
>  	GooString.cc				\
>  	gmem.cc					\
>  	FixedPoint.cc				\
> +	NetPBMWriter.cc				\
>  	PNGWriter.cc				\
>  	JpegWriter.cc				\
>  	TiffWriter.cc				\
> diff --git a/goo/NetPBMWriter.cc b/goo/NetPBMWriter.cc
> new file mode 100644
> index 0000000..fca00b2
> --- /dev/null
> +++ b/goo/NetPBMWriter.cc
> @@ -0,0 +1,84 @@
> +//========================================================================
> +//
> +// NetPBMWriter.h
> +//
> +// Copyright 1998-2003 Glyph & Cog, LLC
> +//
> +//========================================================================
> +//
> +//========================================================================
> +//
> +// Modified under the Poppler project - http://poppler.freedesktop.org
> +//
> +// All changes made under the Poppler project to this file are licensed
> +// under GPL version 2 or later
> +//
> +// Copyright (C) 2005, 2007, 2011 Albert Astals Cid <aacid at kde.org>
> +// Copyright (C) 2006 Rainer Keller <class321 at gmx.de>
> +// Copyright (C) 2008 Timothy Lee <timothy.lee at siriushk.com>
> +// Copyright (C) 2008 Vasile Gaburici <gaburici at cs.umd.edu>
> +// Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
> +// Copyright (C) 2009 William Bader <williambader at hotmail.com>
> +// Copyright (C) 2010 Jakob Voss <jakob.voss at gbv.de>
> +// Copyright (C) 2012, 2013 Adrian Johnson <ajohnson at redneon.com>
> +// Copyright (C) 2013 Thomas Fischer <fischer at unix-ag.uni-kl.de>
> +//
> +// To see a description of the changes please see the Changelog file that
> +// came with your tarball or type make ChangeLog if you are building from
> git +//
> +//========================================================================
> +
> +#include "poppler-config.h"
> +
> +#include "NetPBMWriter.h"
> +
> +// Writer for the NetPBM formats (PBM and PPM)
> +// This format is documented at:
> +//   http://netpbm.sourceforge.net/doc/pbm.html
> +//   http://netpbm.sourceforge.net/doc/ppm.html
> +
> +NetPBMWriter::NetPBMWriter(Format formatA) : format(formatA)
> +{
> +}
> +
> +bool NetPBMWriter::init(FILE *f, int widthA, int heightA, int hDPI, int
> vDPI) +{
> +  file = f;
> +  width = widthA;
> +  if (format == MONOCHROME) {
> +    fprintf(file, "P4\n");
> +    fprintf(file, "%d %d\n", widthA, heightA);
> +  } else {
> +    fprintf(file, "P6\n");
> +    fprintf(file, "%d %d\n", widthA, heightA);
> +    fprintf(file, "255\n");
> +  }
> +  return true;
> +}
> +
> +bool NetPBMWriter::writePointers(unsigned char **rowPointers, int rowCount)
> +{
> +  for (int i = 0; i < rowCount; i++)
> +    writeRow(&rowPointers[i]);
> +  return true;
> +}
> +
> +bool NetPBMWriter::writeRow(unsigned char **row)
> +{
> +  if (format == MONOCHROME) {
> +    // PBM uses 0 = white, 1 = black so we need to invert the colors
> +    int size = (width + 7)/8;
> +    for (int i = 0; i < size; i++)
> +      fputc((*row)[i] ^ 0xff, file);
> +  } else {
> +    fwrite(*row, 1, width*3, file);
> +  }
> +  return true;
> +}
> +
> +
> +bool NetPBMWriter::close()
> +{
> +  return true;
> +}
> +
> diff --git a/goo/NetPBMWriter.h b/goo/NetPBMWriter.h
> new file mode 100644
> index 0000000..21a19ee
> --- /dev/null
> +++ b/goo/NetPBMWriter.h
> @@ -0,0 +1,52 @@
> +//========================================================================
> +//
> +// NetPBMWriter.h
> +//
> +// This file is licensed under the GPLv2 or later
> +//
> +// Copyright (C) 2009 Stefan Thomas <thomas at eload24.com>
> +// Copyright (C) 2009, 2011 Albert Astals Cid <aacid at kde.org>
> +// Copyright (C) 2010, 2013 Adrian Johnson <ajohnson at redneon.com>
> +// Copyright (C) 2010 Brian Cameron <brian.cameron at oracle.com>
> +// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag at alfa.de>
> +//
> +//========================================================================
> +
> +#ifndef NETPBMWRITER_H
> +#define NETPBMWRITER_H
> +
> +#include "poppler-config.h"
> +
> +#include "ImgWriter.h"
> +
> +// Writer for the NetPBM formats (PBM and PPM)
> +// This format is documented at:
> +//   http://netpbm.sourceforge.net/doc/pbm.html
> +//   http://netpbm.sourceforge.net/doc/ppm.html
> +
> +class NetPBMWriter : public ImgWriter
> +{
> +public:
> +
> +  /* RGB        - 3 bytes/pixel
> +   * MONOCHROME - 8 pixels/byte
> +   */
> +  enum Format { RGB, MONOCHROME };
> +
> +  NetPBMWriter(Format formatA = RGB);
> +  ~NetPBMWriter() {};
> +
> +  bool init(FILE *f, int width, int height, int hDPI, int vDPI);
> +
> +  bool writePointers(unsigned char **rowPointers, int rowCount);
> +  bool writeRow(unsigned char **row);
> +
> +  bool close();
> +
> +private:
> +  FILE *file;
> +  Format format;
> +  int width;
> +};
> +
> +#endif
> diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
> index 3b9427b..58f3cd8 100644
> --- a/utils/ImageOutputDev.cc
> +++ b/utils/ImageOutputDev.cc
> @@ -41,6 +41,7 @@
>  #include <ctype.h>
>  #include <math.h>
>  #include "goo/gmem.h"
> +#include "goo/NetPBMWriter.h"
>  #include "Error.h"
>  #include "GfxState.h"
>  #include "Object.h"
> @@ -280,177 +281,145 @@ void ImageOutputDev::listImage(GfxState *state,
> Object *ref, Stream *str, ++imgNum;
>  }
> 
> -void ImageOutputDev::writeMask(GfxState *state, Object *ref, Stream *str,
> -			       int width, int height, GBool invert,
> -			       GBool interpolate, GBool inlineImg) {
> +void ImageOutputDev::writeRawImage(Stream *str, const char *ext) {
>    FILE *f;
>    int c;
> -  int size, i;
> 
> -  // dump JPEG file
> -  if (dumpJPEG && str->getKind() == strDCT && !inlineImg) {
> +  // open the image file
> +  setFilename(ext);
> +  ++imgNum;
> +  if (!(f = fopen(fileName, "wb"))) {
> +    error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> +    return;
> +  }
> 
> -    // open the image file
> -    setFilename("jpg");
> -    ++imgNum;
> -    if (!(f = fopen(fileName, "wb"))) {
> -      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> -      return;
> -    }
> +  // initialize stream
> +  str = str->getNextStream();
> +  str->reset();
> 
> -    // initialize stream
> -    str = str->getNextStream();
> -    str->reset();
> +  // copy the stream
> +  while ((c = str->getChar()) != EOF)
> +    fputc(c, f);
> 
> -    // copy the stream
> -    while ((c = str->getChar()) != EOF)
> -      fputc(c, f);
> +  str->close();
> +  fclose(f);
> +}
> 
> -    str->close();
> -    fclose(f);
> +void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format,
> const char *ext, +                                    Stream *str, int
> width, int height, GfxImageColorMap *colorMap) { +  FILE *f;
> +  ImageStream *imgStr;
> +  unsigned char *row;
> +  unsigned char *rowp;
> +  Guchar *p;
> +  GfxRGB rgb;
> +  GfxGray gray;
> +  Guchar zero = 0;
> +  int invert_bits = 0xff;
> 
> -  // dump PBM file
> -  } else {
> +  setFilename(ext);
> +  ++imgNum;
> +  if (!(f = fopen(fileName, "wb"))) {
> +    error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> +    return;
> +  }
> 
> -    // open the image file and write the PBM header
> -    setFilename("pbm");
> -    ++imgNum;
> -    if (!(f = fopen(fileName, "wb"))) {
> -      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> -      return;
> -    }
> -    fprintf(f, "P4\n");
> -    fprintf(f, "%d %d\n", width, height);
> +  if (!writer->init(f, width, height, 72, 72)) {
> +    error(errIO, -1, "Error writing '{0:s}'", fileName);
> +    return;
> +  }
> 
> +  if (format != imgMonochrome) {
> +    // initialize stream
> +    imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
> +                             colorMap->getBits());
> +    imgStr->reset();
> +  } else {
>      // initialize stream
>      str->reset();
> +  }
> +
> +  row = (unsigned char *) gmallocn(width, sizeof(unsigned int));
> +
> +  // if 0 comes out as 0 in the color map, the we _flip_ stream bits
> +  // otherwise we pass through stream bits unmolested
> +  if (colorMap) {
> +    colorMap->getGray(&zero, &gray);
> +    if (colToByte(gray) == 0)
> +      invert_bits = 0x00;
> +  }
> 
> -    // copy the stream
> -    size = height * ((width + 7) / 8);
> -    for (i = 0; i < size; ++i) {
> -      fputc(str->getChar(), f);
> +  // for each line...
> +  for (int y = 0; y < height; y++) {
> +    switch (format) {
> +    case imgRGB:
> +      p = imgStr->getLine();
> +      rowp = row;
> +      for (int x = 0; x < width; ++x) {
> +        if (p) {
> +          colorMap->getRGB(p, &rgb);
> +          *rowp++ = colToByte(rgb.r);
> +          *rowp++ = colToByte(rgb.g);
> +          *rowp++ = colToByte(rgb.b);
> +          p += colorMap->getNumPixelComps();
> +        } else {
> +          *rowp++ = 0;
> +          *rowp++ = 0;
> +          *rowp++ = 0;
> +        }
> +      }
> +      writer->writeRow(&row);
> +      break;
> +
> +    case imgMonochrome:
> +      int size = (width + 7)/8;
> +      for (int x = 0; x < size; x++)
> +        row[x] = str->getChar() ^ invert_bits;
> +      writer->writeRow(&row);
> +      break;
>      }
> +  }
> 
> -    str->close();
> -    fclose(f);
> +  gfree(row);
> +  if (format != imgMonochrome) {
> +    imgStr->close();
> +    delete imgStr;
>    }
> +  str->close();
> +  writer->close();
> +  fclose(f);
>  }
> 
>  void ImageOutputDev::writeImage(GfxState *state, Object *ref, Stream *str,
>  				int width, int height,
> -				GfxImageColorMap *colorMap,
> -				GBool interpolate, int *maskColors, GBool inlineImg) {
> -  FILE *f;
> -  ImageStream *imgStr;
> -  Guchar *p;
> -  Guchar zero = 0;
> -  GfxGray gray;
> -  GfxRGB rgb;
> -  int x, y;
> -  int c;
> -  int size, i;
> -  int pbm_mask = 0xff;
> +				GfxImageColorMap *colorMap, GBool inlineImg) {
> +  ImageFormat format;
> 
> -  // dump JPEG file
>    if (dumpJPEG && str->getKind() == strDCT &&
>        (colorMap->getNumPixelComps() == 1 ||
>         colorMap->getNumPixelComps() == 3) &&
>        !inlineImg) {
> 
> -    // open the image file
> -    setFilename("jpg");
> -    ++imgNum;
> -    if (!(f = fopen(fileName, "wb"))) {
> -      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> -      return;
> -    }
> -
> -    // initialize stream
> -    str = str->getNextStream();
> -    str->reset();
> -
> -    // copy the stream
> -    while ((c = str->getChar()) != EOF)
> -      fputc(c, f);
> -
> -    str->close();
> -    fclose(f);
> -
> -  // dump PBM file
> -  } else if (colorMap->getNumPixelComps() == 1 &&
> -	     colorMap->getBits() == 1) {
> -
> -    // open the image file and write the PBM header
> -    setFilename("pbm");
> -    ++imgNum;
> -    if (!(f = fopen(fileName, "wb"))) {
> -      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> -      return;
> -    }
> -    fprintf(f, "P4\n");
> -    fprintf(f, "%d %d\n", width, height);
> -
> -    // initialize stream
> -    str->reset();
> -
> -    // if 0 comes out as 0 in the color map, the we _flip_ stream bits
> -    // otherwise we pass through stream bits unmolested
> -    colorMap->getGray(&zero, &gray);
> -    if(colToByte(gray))
> -      pbm_mask = 0;
> -
> -    // copy the stream
> -    size = height * ((width + 7) / 8);
> -    for (i = 0; i < size; ++i) {
> -      fputc(str->getChar() ^ pbm_mask, f);
> -    }
> -
> -    str->close();
> -    fclose(f);
> +    // dump JPEG file
> +    writeRawImage(str, "jpg");
> 
> -  // dump PPM file
>    } else {
> +    ImgWriter *writer;
> 
> -    // open the image file and write the PPM header
> -    setFilename("ppm");
> -    ++imgNum;
> -    if (!(f = fopen(fileName, "wb"))) {
> -      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
> -      return;
> +    // dump PBM file
> +    if (!colorMap || (colorMap->getNumPixelComps() == 1 &&
> colorMap->getBits() == 1)) { +      writer = new
> NetPBMWriter(NetPBMWriter::MONOCHROME);
> +      format = imgMonochrome;
> +    } else {
> +      writer = new NetPBMWriter(NetPBMWriter::RGB);
> +      format = imgRGB;
>      }
> -    fprintf(f, "P6\n");
> -    fprintf(f, "%d %d\n", width, height);
> -    fprintf(f, "255\n");
> -
> -    // initialize stream
> -    imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
> -			     colorMap->getBits());
> -    imgStr->reset();
> 
> -    // for each line...
> -    for (y = 0; y < height; ++y) {
> -
> -      // write the line
> -      if ((p = imgStr->getLine())) {
> -	for (x = 0; x < width; ++x) {
> -	  colorMap->getRGB(p, &rgb);
> -	  fputc(colToByte(rgb.r), f);
> -	  fputc(colToByte(rgb.g), f);
> -	  fputc(colToByte(rgb.b), f);
> -	  p += colorMap->getNumPixelComps();
> -	}
> -      } else {
> -	for (x = 0; x < width; ++x) {
> -	  fputc(0, f);
> -	  fputc(0, f);
> -	  fputc(0, f);
> -	}
> -      }
> -    }
> -    imgStr->close();
> -    delete imgStr;
> +    writeImageFile(writer, format,
> +                   format == imgRGB ? "ppm" : "pbm",
> +                   str, width, height, colorMap);
> 
> -    fclose(f);
> +    delete writer;
>    }
>  }
> 
> @@ -469,7 +438,7 @@ void ImageOutputDev::drawImageMask(GfxState *state,
> Object *ref, Stream *str, if (listImages)
>      listImage(state, ref, str, width, height, NULL, interpolate, inlineImg,
> imgStencil); else
> -    writeMask(state, ref, str, width, height, invert, interpolate,
> inlineImg); +    writeImage(state, ref, str, width, height, NULL,
> inlineImg);
>  }
> 
>  void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
> @@ -479,7 +448,7 @@ void ImageOutputDev::drawImage(GfxState *state, Object
> *ref, Stream *str, if (listImages)
>      listImage(state, ref, str, width, height, colorMap, interpolate,
> inlineImg, imgImage); else
> -    writeImage(state, ref, str, width, height, colorMap, interpolate,
> maskColors, inlineImg); +    writeImage(state, ref, str, width, height,
> colorMap, inlineImg); }
> 
>  void ImageOutputDev::drawMaskedImage(
> @@ -490,9 +459,8 @@ void ImageOutputDev::drawMaskedImage(
>      listImage(state, ref, str, width, height, colorMap, interpolate,
> gFalse, imgImage); listImage(state, ref, str, maskWidth, maskHeight, NULL,
> maskInterpolate, gFalse, imgMask); } else {
> -    drawImage(state, ref, str, width, height, colorMap, interpolate, NULL,
> gFalse); -    drawImageMask(state, ref, maskStr, maskWidth, maskHeight,
> maskInvert, -		  maskInterpolate, gFalse);
> +    writeImage(state, ref, str, width, height, colorMap, gFalse);
> +    writeImage(state, ref, maskStr, maskWidth, maskHeight, NULL, gFalse);
>    }
>  }
> 
> @@ -505,8 +473,7 @@ void ImageOutputDev::drawSoftMaskedImage(
>      listImage(state, ref, str, width, height, colorMap, interpolate,
> gFalse, imgImage); listImage(state, ref, maskStr, maskWidth, maskHeight,
> maskColorMap, maskInterpolate, gFalse, imgSmask); } else {
> -    drawImage(state, ref, str, width, height, colorMap, interpolate, NULL,
> gFalse); -    drawImage(state, ref, maskStr, maskWidth, maskHeight,
> -	      maskColorMap, maskInterpolate, NULL, gFalse);
> +    writeImage(state, ref, str, width, height, colorMap, gFalse);
> +    writeImage(state, ref, maskStr, maskWidth, maskHeight, maskColorMap,
> gFalse); }
>  }
> diff --git a/utils/ImageOutputDev.h b/utils/ImageOutputDev.h
> index 13911ed..d89836f 100644
> --- a/utils/ImageOutputDev.h
> +++ b/utils/ImageOutputDev.h
> @@ -36,6 +36,7 @@
> 
>  #include <stdio.h>
>  #include "goo/gtypes.h"
> +#include "goo/ImgWriter.h"
>  #include "OutputDev.h"
> 
>  class GfxState;
> @@ -52,6 +53,10 @@ public:
>      imgMask,
>      imgSmask
>    };
> +  enum ImageFormat {
> +    imgRGB,
> +    imgMonochrome
> +  };
> 
>    // Create an OutputDev which will write images to files named
>    // <fileRoot>-NNN.<type> or <fileRoot>-PPP-NNN.<type>, if
> @@ -128,13 +133,11 @@ private:
>  		 GfxImageColorMap *colorMap,
>  		 GBool interpolate, GBool inlineImg,
>  		 ImageType imageType);
> -  void writeMask(GfxState *state, Object *ref, Stream *str,
> -		 int width, int height, GBool invert,
> -		 GBool interpolate, GBool inlineImg);
>    void writeImage(GfxState *state, Object *ref, Stream *str,
> -                  int width, int height, GfxImageColorMap *colorMap,
> -                  GBool interpolate, int *maskColors, GBool inlineImg);
> -
> +                  int width, int height, GfxImageColorMap *colorMap, GBool
> inlineImg); +  void writeRawImage(Stream *str, const char *ext);
> +  void writeImageFile(ImgWriter *writer, ImageFormat format, const char
> *ext, +                      Stream *str, int width, int height,
> GfxImageColorMap *colorMap);
> 
>    char *fileRoot;		// root of output file names
>    char *fileName;		// buffer for output file names
> commit 0ca0fcc9f536a57365048914cd8a8cc3eb5ed4fd
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Sat Aug 17 15:24:43 2013 +0930
> 
>     pdfimages: fix bug in -list output
> 
>     Images of type /ImageMask should have type 'stencil'.
> 
> diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
> index 1d1064b..3b9427b 100644
> --- a/utils/ImageOutputDev.cc
> +++ b/utils/ImageOutputDev.cc
> @@ -467,7 +467,7 @@ void ImageOutputDev::drawImageMask(GfxState *state,
> Object *ref, Stream *str, int width, int height, GBool invert,
>  				   GBool interpolate, GBool inlineImg) {
>    if (listImages)
> -    listImage(state, ref, str, width, height, NULL, interpolate, inlineImg,
> imgMask); +    listImage(state, ref, str, width, height, NULL, interpolate,
> inlineImg, imgStencil); else
>      writeMask(state, ref, str, width, height, invert, interpolate,
> inlineImg); }
> commit f8ee5a931c795013d17f73f083b6e6f9a683d061
> Author: Adrian Johnson <ajohnson at redneon.com>
> Date:   Sat Aug 17 15:17:11 2013 +0930
> 
>     pdfimages: print size, ratio, and ppi
> 
> diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
> index 8b18d2b..1d1064b 100644
> --- a/utils/ImageOutputDev.cc
> +++ b/utils/ImageOutputDev.cc
> @@ -20,7 +20,7 @@
>  // Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
>  // Copyright (C) 2009 William Bader <williambader at hotmail.com>
>  // Copyright (C) 2010 Jakob Voss <jakob.voss at gbv.de>
> -// Copyright (C) 2012 Adrian Johnson <ajohnson at redneon.com>
> +// Copyright (C) 2012, 2013 Adrian Johnson <ajohnson at redneon.com>
>  // Copyright (C) 2013 Thomas Fischer <fischer at unix-ag.uni-kl.de>
>  //
>  // To see a description of the changes please see the Changelog file that
> @@ -39,6 +39,7 @@
>  #include <stdlib.h>
>  #include <stddef.h>
>  #include <ctype.h>
> +#include <math.h>
>  #include "goo/gmem.h"
>  #include "Error.h"
>  #include "GfxState.h"
> @@ -58,8 +59,8 @@ ImageOutputDev::ImageOutputDev(char *fileRootA, GBool
> pageNamesA, GBool dumpJPEG pageNum = 0;
>    ok = gTrue;
>    if (listImages) {
> -    printf("page   num  type   width height color comp bpc  enc interp 
> object ID\n"); -   
> printf("-------------------------------------------------------------------
> --\n"); +    printf("page   num  type   width height color comp bpc  enc
> interp  object ID x-ppi y-ppi size ratio\n"); +   
> printf("-------------------------------------------------------------------
> -------------------------\n"); }
>  }
> 
> @@ -79,6 +80,34 @@ void ImageOutputDev::setFilename(const char *fileExt) {
>    }
>  }
> 
> +
> +// Print a floating point number between 0 - 9999 using 4 characters
> +// eg '1.23', '12.3', ' 123', '1234'
> +//
> +// We need to be careful to handle the cases where rounding adds an
> +// extra digit before the decimal. eg printf("%4.2f", 9.99999)
> +// outputs "10.00" instead of "9.99".
> +static void printNumber(double d)
> +{
> +  char buf[10];
> +
> +  if (d < 10.0) {
> +    sprintf(buf, "%4.2f", d);
> +    buf[4] = 0;
> +    printf("%s", buf);
> +  } else if (d < 100.0) {
> +    sprintf(buf, "%4.1f", d);
> +    if (!isdigit(buf[3])) {
> +      buf[3] = 0;
> +      printf(" %s", buf);
> +    } else {
> +      printf("%s", buf);
> +    }
> +  } else {
> +    printf("%4.0f", d);
> +  }
> +}
> +
>  void ImageOutputDev::listImage(GfxState *state, Object *ref, Stream *str,
>  			       int width, int height,
>  			       GfxImageColorMap *colorMap,
> @@ -179,18 +208,75 @@ void ImageOutputDev::listImage(GfxState *state, Object
> *ref, Stream *str, printf("%-3s  ", interpolate ? "yes" : "no");
> 
>    if (inlineImg) {
> -    printf("[inline]\n");
> +    printf("[inline]   ");
>    } else if (ref->isRef()) {
>      const Ref imageRef = ref->getRef();
>      if (imageRef.gen >= 100000) {
> -      printf("[none]\n");
> +      printf("[none]     ");
>      } else {
> -      printf(" %6d %2d\n", imageRef.num, imageRef.gen);
> +      printf(" %6d %2d ", imageRef.num, imageRef.gen);
>      }
>    } else {
> -    printf("[none]\n");
> +    printf("[none]     ");
> +  }
> +
> +  double *mat = state->getCTM();
> +  double width2 = mat[0] + mat[2];
> +  double height2 = mat[1] + mat[3];
> +  double xppi = fabs(width*72.0/width2) + 0.5;
> +  double yppi = fabs(height*72.0/height2) + 0.5;
> +  if (xppi < 1.0)
> +    printf("%5.3f ", xppi);
> +  else
> +    printf("%5.0f ", xppi);
> +  if (yppi < 1.0)
> +    printf("%5.3f ", yppi);
> +  else
> +    printf("%5.0f ", yppi);
> +
> +  Goffset embedSize = -1;
> +  if (!inlineImg)
> +    embedSize = str->getBaseStream()->getLength();
> +
> +  long long imageSize = 0;
> +  if (colorMap && colorMap->isOk())
> +    imageSize = ((long long)width * height * colorMap->getNumPixelComps() *
> colorMap->getBits())/8; +  else
> +    imageSize = (long long)width*height/8; // mask
> +
> +  double ratio = -1.0;
> +  if (imageSize > 0)
> +    ratio = 100.0*embedSize/imageSize;
> +
> +  if (embedSize < 0) {
> +    printf("   - ");
> +  } else if (embedSize <= 9999) {
> +    printf("%4lldB", embedSize);
> +  } else {
> +    double d = embedSize/1024.0;
> +    if (d <= 9999.0) {
> +      printNumber(d);
> +      putchar('K');
> +    } else {
> +      d /= 1024.0;
> +      if (d <= 9999.0) {
> +        printNumber(d);
> +        putchar('M');
> +      } else {
> +        d /= 1024.0;
> +        printNumber(d);
> +        putchar('G');
> +      }
> +    }
>    }
> 
> +  if (ratio > 9.9)
> +    printf(" %3.0f%%\n", ratio);
> +  else if (ratio >= 0.0)
> +    printf(" %3.1f%%\n", ratio);
> +  else
> +    printf("   - \n");
> +
>    ++imgNum;
>  }
> 
> diff --git a/utils/pdfimages.1 b/utils/pdfimages.1
> index 955d8b3..e98bf29 100644
> --- a/utils/pdfimages.1
> +++ b/utils/pdfimages.1
> @@ -134,6 +134,18 @@ ccitt - CCITT Group 3 or Group 4 Fax
>  .TP
>  .B object ID
>  the font dictionary object ID (number and generation)
> +.TP
> +.B x\-ppi
> +The horizontal resolution of the image (in pixels per inch) when rendered
> on the pdf page. +.TP
> +.B y\-ppi
> +The vertical resolution of the image (in pixels per inch) when rendered on
> the pdf page. +.TP
> +.B size
> +The size of the embedded image in the pdf file. The following suffixes are
> used: 'B' bytes, 'K' kilobytes, 'M' megabytes, and 'G' gigabytes. +.TP
> +.B ratio
> +The compression ratio of the embedded image.
>  .RE
>  .TP
>  .BI \-opw " password"
> diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc
> index 82c301c..7b6cad0 100644
> --- a/utils/pdfimages.cc
> +++ b/utils/pdfimages.cc
> @@ -18,7 +18,7 @@
>  // Copyright (C) 2007-2008, 2010 Albert Astals Cid <aacid at kde.org>
>  // Copyright (C) 2010 Hib Eris <hib at hiberis.nl>
>  // Copyright (C) 2010 Jakob Voss <jakob.voss at gbv.de>
> -// Copyright (C) 2012 Adrian Johnson <ajohnson at redneon.com>
> +// Copyright (C) 2012, 2013 Adrian Johnson <ajohnson at redneon.com>
>  //
>  // To see a description of the changes please see the Changelog file that
>  // came with your tarball or type make ChangeLog if you are building from
> git _______________________________________________
> poppler mailing list
> poppler at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/poppler



More information about the poppler mailing list