beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / goo / TiffWriter.cc
blob316008778b1f5e02bee79ab5669beebf3b65a1cd
1 //========================================================================
2 //
3 // TiffWriter.cc
4 //
5 // This file is licensed under the GPLv2 or later
6 //
7 // Copyright (C) 2010, 2012 William Bader <williambader@hotmail.com>
8 // Copyright (C) 2012 Albert Astals Cid <aacid@kde.org>
9 // Copyright (C) 2012 Adrian Johnson <ajohnson@redneon.com>
10 // Copyright (C) 2012 Pino Toscano <pino@kde.org>
11 // Copyright (C) 2014 Steven Lee <roc.sky@gmail.com>
13 //========================================================================
15 #include "TiffWriter.h"
17 #if ENABLE_LIBTIFF
19 #include <string.h>
21 #ifdef _WIN32
22 #include <io.h>
23 #endif
25 extern "C" {
26 #include <tiffio.h>
29 struct TiffWriterPrivate {
30 TIFF *f; // LibTiff file context
31 int numRows; // number of rows in the image
32 int curRow; // number of rows written
33 const char *compressionString; // compression type
34 TiffWriter::Format format; // format of image data
37 TiffWriter::~TiffWriter()
39 delete priv;
42 TiffWriter::TiffWriter(Format formatA)
44 priv = new TiffWriterPrivate;
45 priv->f = NULL;
46 priv->numRows = 0;
47 priv->curRow = 0;
48 priv->compressionString = NULL;
49 priv->format = formatA;
52 // Set the compression type
54 void TiffWriter::setCompressionString(const char *compressionStringArg)
56 priv->compressionString = compressionStringArg;
59 // Write a TIFF file.
61 bool TiffWriter::init(FILE *openedFile, int width, int height, int hDPI, int vDPI)
63 unsigned int compression;
64 uint16 photometric = 0;
65 uint32 rowsperstrip = (uint32) -1;
66 int bitspersample;
67 uint16 samplesperpixel = 0;
68 const struct compression_name_tag {
69 const char *compressionName; // name of the compression option from the command line
70 unsigned int compressionCode; // internal libtiff code
71 const char *compressionDescription; // descriptive name
72 } compressionList[] = {
73 { "none", COMPRESSION_NONE, "no compression" },
74 { "ccittrle", COMPRESSION_CCITTRLE, "CCITT modified Huffman RLE" },
75 { "ccittfax3", COMPRESSION_CCITTFAX3,"CCITT Group 3 fax encoding" },
76 { "ccittt4", COMPRESSION_CCITT_T4, "CCITT T.4 (TIFF 6 name)" },
77 { "ccittfax4", COMPRESSION_CCITTFAX4, "CCITT Group 4 fax encoding" },
78 { "ccittt6", COMPRESSION_CCITT_T6, "CCITT T.6 (TIFF 6 name)" },
79 { "lzw", COMPRESSION_LZW, "Lempel-Ziv & Welch" },
80 { "ojpeg", COMPRESSION_OJPEG, "!6.0 JPEG" },
81 { "jpeg", COMPRESSION_JPEG, "%JPEG DCT compression" },
82 { "next", COMPRESSION_NEXT, "NeXT 2-bit RLE" },
83 { "packbits", COMPRESSION_PACKBITS, "Macintosh RLE" },
84 { "ccittrlew", COMPRESSION_CCITTRLEW, "CCITT modified Huffman RLE w/ word alignment" },
85 { "deflate", COMPRESSION_DEFLATE, "Deflate compression" },
86 { "adeflate", COMPRESSION_ADOBE_DEFLATE, "Deflate compression, as recognized by Adobe" },
87 { "dcs", COMPRESSION_DCS, "Kodak DCS encoding" },
88 { "jbig", COMPRESSION_JBIG, "ISO JBIG" },
89 { "jp2000", COMPRESSION_JP2000, "Leadtools JPEG2000" },
90 { NULL, 0, NULL }
93 // Initialize
95 priv->f = NULL;
96 priv->curRow = 0;
98 // Store the number of rows
100 priv->numRows = height;
102 // Set the compression
104 compression = COMPRESSION_NONE;
106 if (priv->compressionString == NULL || strcmp(priv->compressionString, "") == 0) {
107 compression = COMPRESSION_NONE;
108 } else {
109 int i;
110 for (i = 0; compressionList[i].compressionName != NULL; i++) {
111 if (strcmp(priv->compressionString, compressionList[i].compressionName) == 0) {
112 compression = compressionList[i].compressionCode;
113 break;
116 if (compressionList[i].compressionName == NULL) {
117 fprintf(stderr, "TiffWriter: Unknown compression type '%.10s', using 'none'.\n", priv->compressionString);
118 fprintf(stderr, "Known compression types (the tiff library might not support every type)\n");
119 for (i = 0; compressionList[i].compressionName != NULL; i++) {
120 fprintf(stderr, "%10s %s\n", compressionList[i].compressionName, compressionList[i].compressionDescription);
125 // Set bits per sample, samples per pixel, and photometric type from format
127 bitspersample = (priv->format == MONOCHROME ? 1 : 8);
129 switch (priv->format) {
130 case MONOCHROME:
131 case GRAY:
132 samplesperpixel = 1;
133 photometric = PHOTOMETRIC_MINISBLACK;
134 break;
136 case RGB:
137 samplesperpixel = 3;
138 photometric = PHOTOMETRIC_RGB;
139 break;
141 case RGBA_PREMULTIPLIED:
142 samplesperpixel = 4;
143 photometric = PHOTOMETRIC_RGB;
144 break;
146 case CMYK:
147 samplesperpixel = 4;
148 photometric = PHOTOMETRIC_SEPARATED;
149 break;
152 // Open the file
154 if (openedFile == NULL) {
155 fprintf(stderr, "TiffWriter: No output file given.\n");
156 return false;
159 #ifdef _WIN32
160 //Convert C Library handle to Win32 Handle
161 priv->f = TIFFFdOpen(_get_osfhandle(fileno(openedFile)), "-", "w");
162 #else
163 priv->f = TIFFFdOpen(fileno(openedFile), "-", "w");
164 #endif
167 if (!priv->f) {
168 return false;
171 // Set TIFF tags
173 TIFFSetField(priv->f, TIFFTAG_IMAGEWIDTH, width);
174 TIFFSetField(priv->f, TIFFTAG_IMAGELENGTH, height);
175 TIFFSetField(priv->f, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
176 TIFFSetField(priv->f, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
177 TIFFSetField(priv->f, TIFFTAG_BITSPERSAMPLE, bitspersample);
178 TIFFSetField(priv->f, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
179 TIFFSetField(priv->f, TIFFTAG_PHOTOMETRIC, photometric);
180 TIFFSetField(priv->f, TIFFTAG_COMPRESSION, (uint16) compression);
181 TIFFSetField(priv->f, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(priv->f, rowsperstrip));
182 TIFFSetField(priv->f, TIFFTAG_XRESOLUTION, (double) hDPI);
183 TIFFSetField(priv->f, TIFFTAG_YRESOLUTION, (double) vDPI);
184 TIFFSetField(priv->f, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
186 if (priv->format == RGBA_PREMULTIPLIED) {
187 uint16 extra = EXTRASAMPLE_ASSOCALPHA;
188 TIFFSetField(priv->f, TIFFTAG_EXTRASAMPLES, 1, &extra);
191 if (priv->format == CMYK) {
192 TIFFSetField(priv->f, TIFFTAG_INKSET, INKSET_CMYK);
193 TIFFSetField(priv->f, TIFFTAG_NUMBEROFINKS, 4);
196 return true;
199 bool TiffWriter::writePointers(unsigned char **rowPointers, int rowCount)
201 // Write all rows to the file
203 for (int row = 0; row < rowCount; row++) {
204 if (TIFFWriteScanline(priv->f, rowPointers[row], row, 0) < 0) {
205 fprintf(stderr, "TiffWriter: Error writing tiff row %d\n", row);
206 return false;
210 return true;
213 bool TiffWriter::writeRow(unsigned char **rowData)
215 // Add a single row
217 if (TIFFWriteScanline(priv->f, *rowData, priv->curRow, 0) < 0) {
218 fprintf(stderr, "TiffWriter: Error writing tiff row %d\n", priv->curRow);
219 return false;
222 priv->curRow++;
224 return true;
227 bool TiffWriter::close()
229 // Close the file
231 TIFFClose(priv->f);
233 return true;
236 #endif