1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-indent-level: 8; c-basic-offset: 8 -*- */
3 * Copyright (C) 2003 Remi Cohen-Scali
6 * Remi Cohen-Scali <Remi@Cohen-Scali.com>
8 * GPdf is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * GPdf is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 * License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
26 #ifdef USE_GCC_PRAGMAS
27 #pragma implementation
30 #include <gpdf-g-switch.h>
32 #include <gpdf-g-switch.h>
39 static GHashTable *cmhash = NULL;
44 ThumbColorMap::ThumbColorMap(int bitsA,
53 GfxIndexedColorSpace *iCS;
54 GfxSeparationColorSpace *sepCS;
55 int maxPixel, indexHigh;
60 int colors = 0, early = 0;
62 int encoding = 0, rows = 0;
63 GBool eol = gFalse, byteAlign = gFalse, eob = gFalse, black = gFalse;
65 int pred = 0, cols = 0;
68 maxPixel = (1 << bits) - 1;
71 if (!obj->isStream ()) {
72 printf ("Error: Invalid object of type %s\n",
76 str = obj->getStream();
78 streamDict = obj->streamGetDict ();
80 streamDict->lookupNF ("Filter", &obj1);
81 if (!obj1.isArray ()) {
82 printf ("Error: Invalid filter object of type %s\n",
87 str = str->addFilters(obj);
89 streamDict->lookup ("Length", &obj1);
92 printf ("Error: No Length object\n");
96 printf ("Error: Invalid Width object %s\n",
101 length = obj1.getInt ();
104 nComps = cs->getNComps();
106 if (cs->getMode () == csIndexed) {
107 iCS = (GfxIndexedColorSpace *)cs;
108 baseNComps = iCS->getBase ()->getNComps ();
110 if (iCS->getBase ()->getMode () == csDeviceGray) {
111 gray = (double *)gmalloc(sizeof(double) * (iCS->getIndexHigh () + 1));
112 for (n = 0; n <= iCS->getIndexHigh (); n++) {
113 double comp = (double)str->getChar();
114 //printf ("Gray pixel [%03d] = %02x\n", n, (int)comp);
115 gray[n] = comp / (double)iCS->getIndexHigh ();
118 else if (iCS->getBase ()->getMode () == csDeviceRGB) {
119 rgb = (GfxRGB *)gmalloc(sizeof(GfxRGB) * (iCS->getIndexHigh () + 1));
120 for (n = 0; n <= iCS->getIndexHigh (); n++) {
121 double comp_r = (double)str->getChar();
122 double comp_g = (double)str->getChar();
123 double comp_b = (double)str->getChar();
124 // printf ("RGB pixel [0x%02x] = (%02x,%02x,%02x)\n",
125 // n, (int)comp_r, (int)comp_g, (int)comp_b);
126 rgb[n].r = comp_r / (double)iCS->getIndexHigh ();
127 rgb[n].g = comp_g / (double)iCS->getIndexHigh ();
128 rgb[n].b = comp_b / (double)iCS->getIndexHigh ();
131 else if (iCS->getBase ()->getMode () == csDeviceCMYK) {
132 cmyk = (GfxCMYK *)gmalloc(sizeof(GfxCMYK) * (iCS->getIndexHigh () + 1));
133 for (n = 0; n <= iCS->getIndexHigh (); n++) {
134 double comp_c = (double)str->getChar();
135 double comp_m = (double)str->getChar();
136 double comp_y = (double)str->getChar();
137 double comp_k = (double)str->getChar();
138 //printf ("CMYK pixel [%03d] = (%02x,%02x,%02x,%02x)\n",
139 // n, (int)comp_c, (int)comp_m, (int)comp_y, (int)comp_k);
140 cmyk[n].c = comp_c / (double)iCS->getIndexHigh ();
141 cmyk[n].m = comp_m / (double)iCS->getIndexHigh ();
142 cmyk[n].y = comp_y / (double)iCS->getIndexHigh ();
143 cmyk[n].k = comp_k / (double)iCS->getIndexHigh ();
147 else if (cs->getMode () == csSeparation) {
148 sepCS = (GfxSeparationColorSpace *)cs;
149 /* FIXME: still to do */
158 ThumbColorMap::lookupColorMap(XRef *xref, int bits, Object *obj, GfxColorSpace *cs)
165 cmhash = g_hash_table_new(NULL, g_int_equal);
167 key = g_strdup_printf ("%d %d R", obj->getRefNum (), obj->getRefGen ());
169 if (!(cm = (ThumbColorMap *)g_hash_table_lookup (cmhash, &key))) {
170 cm = new ThumbColorMap(bits, obj->fetch(xref, &obj1), cs);
172 g_hash_table_insert(cmhash, &key, cm);
181 ThumbColorMap::getGray(Guchar *x, double *outgray)
187 ThumbColorMap::getRGB(Guchar *x, GfxRGB *outrgb)
189 outrgb->r = rgb[*x].r;
190 outrgb->g = rgb[*x].g;
191 outrgb->b = rgb[*x].b;
195 ThumbColorMap::getCMYK(Guchar *x, GfxCMYK *outcmyk)
197 outcmyk->c = cmyk[*x].c;
198 outcmyk->m = cmyk[*x].m;
199 outcmyk->y = cmyk[*x].y;
200 outcmyk->k = cmyk[*x].k;
203 ThumbColorMap::~ThumbColorMap()
213 Thumb::Thumb(XRef *xrefA, Object *obj) :
223 /* Get stream dict */
224 dict = obj->streamGetDict ();
225 str = obj->getStream();
228 dict->lookup ("Width", &obj1);
232 dict->lookup ("W", &obj1);
234 if (!obj1.isInt ()) {
235 printf ("Error: Invalid Width object %s\n",
236 obj1.getTypeName ());
240 width = obj1.getInt ();
244 dict->lookup ("Height", &obj1);
248 dict->lookup ("H", &obj1);
250 if (!obj1.isInt ()) {
251 printf ("Error: Invalid Height object %s\n",
252 obj1.getTypeName ());
256 height = obj1.getInt ();
260 dict->lookup ("BitsPerComponent", &obj1);
264 dict->lookup ("BPC", &obj1);
266 if (!obj1.isInt ()) {
267 printf ("Error: Invalid BitsPerComponent object %s\n",
268 obj1.getTypeName ());
272 bits = obj1.getInt ();
275 /* Get color space */
276 dict->lookup ("ColorSpace", &obj1);
280 dict->lookup ("CS", &obj1);
282 if (!(gfxCS = GfxColorSpace::parse (&obj1)))
284 printf ("Error: Cannot parse color space\n");
288 if (gfxCS->getMode () == csIndexed)
289 thumbCM = ThumbColorMap::lookupColorMap (xref, bits, obj1.arrayGetNF(3, &obj2), gfxCS);
290 else if (gfxCS->getMode () == csSeparation)
291 printf ("Not yet implemented\n");
294 dict->lookup ("Length", &obj1);
295 if (!obj1.isInt ()) {
296 printf ("Error: Invalid Length Object %s\n",
297 obj1.getTypeName ());
301 length = obj1.getInt ();
304 str->addFilters(obj);
310 Thumb::getPixbufData()
313 unsigned char *pixbufdata;
314 unsigned int pixbufdatasize;
318 /* RGB Pixbuf data */
319 pixbufdatasize = width * height * 3;
320 pixbufdata =(unsigned char *)g_malloc(pixbufdatasize);
323 imgstr = new ImageStream(str, width, thumbCM->getNumPixelComps(), thumbCM->getBits());
325 for (row = 0; row < height; ++row) {
326 for (col = 0; col < width; ++col) {
327 Guchar pix[gfxColorMaxComps];
330 imgstr->getPixel(pix);
331 thumbCM->getRGB(pix, &rgb);
333 *p++ = (guchar)(rgb.r * 255.99999);
334 *p++ = (guchar)(rgb.g * 255.99999);
335 *p++ = (guchar)(rgb.b * 255.99999);