source: trunk/poppler/mypoppler/splash/SplashBitmap.cc @ 461

Last change on this file since 461 was 461, checked in by Silvan Scherrer, 11 years ago

poppler update to 0.14.2

File size: 9.2 KB
Line 
1//========================================================================
2//
3// SplashBitmap.cc
4//
5//========================================================================
6
7//========================================================================
8//
9// Modified under the Poppler project - http://poppler.freedesktop.org
10//
11// All changes made under the Poppler project to this file are licensed
12// under GPL version 2 or later
13//
14// Copyright (C) 2006, 2009, 2010 Albert Astals Cid <aacid@kde.org>
15// Copyright (C) 2007 Ilmari Heikkinen <ilmari.heikkinen@gmail.com>
16// Copyright (C) 2009 Shen Liang <shenzhuxi@gmail.com>
17// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
18// Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
19// Copyright (C) 2010 Harry Roberts <harry.roberts@midnight-labs.org>
20//
21// To see a description of the changes please see the Changelog file that
22// came with your tarball or type make ChangeLog if you are building from git
23//
24//========================================================================
25
26#include <config.h>
27
28#ifdef USE_GCC_PRAGMAS
29#pragma implementation
30#endif
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <limits.h>
35#include "goo/gmem.h"
36#include "SplashErrorCodes.h"
37#include "SplashBitmap.h"
38#include "poppler/Error.h"
39#include "goo/JpegWriter.h"
40#include "goo/PNGWriter.h"
41#include "goo/ImgWriter.h"
42
43//------------------------------------------------------------------------
44// SplashBitmap
45//------------------------------------------------------------------------
46
47SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
48                           SplashColorMode modeA, GBool alphaA,
49                           GBool topDown) {
50  width = widthA;
51  height = heightA;
52  mode = modeA;
53  switch (mode) {
54  case splashModeMono1:
55    if (width > 0) {
56      rowSize = (width + 7) >> 3;
57    } else {
58      rowSize = -1;
59    }
60    break;
61  case splashModeMono8:
62    if (width > 0) {
63      rowSize = width;
64    } else {
65      rowSize = -1;
66    }
67    break;
68  case splashModeRGB8:
69  case splashModeBGR8:
70    if (width > 0 && width <= INT_MAX / 3) {
71      rowSize = width * 3;
72    } else {
73      rowSize = -1;
74    }
75    break;
76  case splashModeXBGR8:
77    if (width > 0 && width <= INT_MAX / 4) {
78      rowSize = width * 4;
79    } else {
80      rowSize = -1;
81    }
82    break;
83#if SPLASH_CMYK
84  case splashModeCMYK8:
85    if (width > 0 && width <= INT_MAX / 4) {
86      rowSize = width * 4;
87    } else {
88      rowSize = -1;
89    }
90    break;
91#endif
92  }
93  if (rowSize > 0) {
94    rowSize += rowPad - 1;
95    rowSize -= rowSize % rowPad;
96  }
97  data = (SplashColorPtr)gmallocn(rowSize, height);
98  if (!topDown) {
99    data += (height - 1) * rowSize;
100    rowSize = -rowSize;
101  }
102  if (alphaA) {
103    alpha = (Guchar *)gmallocn(width, height);
104  } else {
105    alpha = NULL;
106  }
107}
108
109
110SplashBitmap::~SplashBitmap() {
111  if (rowSize < 0) {
112    gfree(data + (height - 1) * rowSize);
113  } else {
114    gfree(data);
115  }
116  gfree(alpha);
117}
118
119
120SplashError SplashBitmap::writePNMFile(char *fileName) {
121  FILE *f;
122  SplashError e;
123
124  if (!(f = fopen(fileName, "wb"))) {
125    return splashErrOpenFile;
126  }
127
128  e = this->writePNMFile(f);
129 
130  fclose(f);
131  return e;
132}
133
134
135SplashError SplashBitmap::writePNMFile(FILE *f) {
136  SplashColorPtr row, p;
137  int x, y;
138
139  switch (mode) {
140
141  case splashModeMono1:
142    fprintf(f, "P4\n%d %d\n", width, height);
143    row = data;
144    for (y = 0; y < height; ++y) {
145      p = row;
146      for (x = 0; x < width; x += 8) {
147        fputc(*p ^ 0xff, f);
148        ++p;
149      }
150      row += rowSize;
151    }
152    break;
153
154  case splashModeMono8:
155    fprintf(f, "P5\n%d %d\n255\n", width, height);
156    row = data;
157    for (y = 0; y < height; ++y) {
158      p = row;
159      for (x = 0; x < width; ++x) {
160        fputc(*p, f);
161        ++p;
162      }
163      row += rowSize;
164    }
165    break;
166
167  case splashModeRGB8:
168    fprintf(f, "P6\n%d %d\n255\n", width, height);
169    row = data;
170    for (y = 0; y < height; ++y) {
171      p = row;
172      for (x = 0; x < width; ++x) {
173        fputc(splashRGB8R(p), f);
174        fputc(splashRGB8G(p), f);
175        fputc(splashRGB8B(p), f);
176        p += 3;
177      }
178      row += rowSize;
179    }
180    break;
181
182  case splashModeXBGR8:
183    fprintf(f, "P6\n%d %d\n255\n", width, height);
184    row = data;
185    for (y = 0; y < height; ++y) {
186      p = row;
187      for (x = 0; x < width; ++x) {
188        fputc(splashBGR8R(p), f);
189        fputc(splashBGR8G(p), f);
190        fputc(splashBGR8B(p), f);
191        p += 4;
192      }
193      row += rowSize;
194    }
195    break;
196
197
198  case splashModeBGR8:
199    fprintf(f, "P6\n%d %d\n255\n", width, height);
200    row = data;
201    for (y = 0; y < height; ++y) {
202      p = row;
203      for (x = 0; x < width; ++x) {
204        fputc(splashBGR8R(p), f);
205        fputc(splashBGR8G(p), f);
206        fputc(splashBGR8B(p), f);
207        p += 3;
208      }
209      row += rowSize;
210    }
211    break;
212
213#if SPLASH_CMYK
214  case splashModeCMYK8:
215    // PNM doesn't support CMYK
216    error(-1, "unsupported SplashBitmap mode");
217    return splashErrGeneric;
218    break;
219#endif
220  }
221  return splashOk;
222}
223
224
225void SplashBitmap::getPixel(int x, int y, SplashColorPtr pixel) {
226  SplashColorPtr p;
227
228  if (y < 0 || y >= height || x < 0 || x >= width) {
229    return;
230  }
231  switch (mode) {
232  case splashModeMono1:
233    p = &data[y * rowSize + (x >> 3)];
234    pixel[0] = (p[0] & (0x80 >> (x & 7))) ? 0xff : 0x00;
235    break;
236  case splashModeMono8:
237    p = &data[y * rowSize + x];
238    pixel[0] = p[0];
239    break;
240  case splashModeRGB8:
241    p = &data[y * rowSize + 3 * x];
242    pixel[0] = p[0];
243    pixel[1] = p[1];
244    pixel[2] = p[2];
245    break;
246  case splashModeXBGR8:
247    p = &data[y * rowSize + 4 * x];
248    pixel[0] = p[2];
249    pixel[1] = p[1];
250    pixel[2] = p[0];
251    pixel[3] = p[3];
252    break;
253  case splashModeBGR8:
254    p = &data[y * rowSize + 3 * x];
255    pixel[0] = p[2];
256    pixel[1] = p[1];
257    pixel[2] = p[0];
258    break;
259#if SPLASH_CMYK
260  case splashModeCMYK8:
261    p = &data[y * rowSize + 4 * x];
262    pixel[0] = p[0];
263    pixel[1] = p[1];
264    pixel[2] = p[2];
265    pixel[3] = p[3];
266    break;
267#endif
268  }
269}
270
271Guchar SplashBitmap::getAlpha(int x, int y) {
272  return alpha[y * width + x];
273}
274
275SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, char *fileName, int hDPI, int vDPI) {
276  FILE *f;
277  SplashError e;
278
279  if (!(f = fopen(fileName, "wb"))) {
280    return splashErrOpenFile;
281  }
282
283  e = writeImgFile(format, f, hDPI, vDPI);
284 
285  fclose(f);
286  return e;
287}
288
289SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI) {
290  ImgWriter *writer;
291        SplashError e;
292 
293  switch (format) {
294    #ifdef ENABLE_LIBPNG
295    case splashFormatPng:
296          writer = new PNGWriter();
297      break;
298    #endif
299
300    #ifdef ENABLE_LIBJPEG
301    case splashFormatJpeg:
302      writer = new JpegWriter();
303      break;
304    #endif
305       
306    default:
307      // Not the greatest error message, but users of this function should
308      // have already checked whether their desired format is compiled in.
309      error(-1, "Support for this image type not compiled in");
310      return splashErrGeneric;
311  }
312
313        e = writeImgFile(writer, f, hDPI, vDPI);
314        delete writer;
315        return e;
316}
317
318SplashError SplashBitmap::writeImgFile(ImgWriter *writer, FILE *f, int hDPI, int vDPI) {
319  if (mode != splashModeRGB8 && mode != splashModeMono8 && mode != splashModeMono1 && mode != splashModeXBGR8) {
320    error(-1, "unsupported SplashBitmap mode");
321    return splashErrGeneric;
322  }
323
324  if (!writer->init(f, width, height, hDPI, vDPI)) {
325    return splashErrGeneric;
326  }
327
328  switch (mode) {
329    case splashModeRGB8:
330    {
331      SplashColorPtr row;
332      unsigned char **row_pointers = new unsigned char*[height];
333      row = data;
334
335      for (int y = 0; y < height; ++y) {
336        row_pointers[y] = row;
337        row += rowSize;
338      }
339      if (!writer->writePointers(row_pointers, height)) {
340        delete[] row_pointers;
341        return splashErrGeneric;
342      }
343      delete[] row_pointers;
344    }
345    break;
346   
347    case splashModeXBGR8:
348    {
349      unsigned char *row = new unsigned char[3 * width];
350      for (int y = 0; y < height; y++) {
351        // Convert into a PNG row
352        for (int x = 0; x < width; x++) {
353          row[3*x] = data[y * rowSize + x * 4 + 2];
354          row[3*x+1] = data[y * rowSize + x * 4 + 1];
355          row[3*x+2] = data[y * rowSize + x * 4];
356        }
357
358        if (!writer->writeRow(&row)) {
359          delete[] row;
360          return splashErrGeneric;
361        }
362      }
363      delete[] row;
364    }
365    break;
366   
367    case splashModeMono8:
368    {
369      unsigned char *row = new unsigned char[3 * width];
370      for (int y = 0; y < height; y++) {
371        // Convert into a PNG row
372        for (int x = 0; x < width; x++) {
373          row[3*x] = data[y * rowSize + x];
374          row[3*x+1] = data[y * rowSize + x];
375          row[3*x+2] = data[y * rowSize + x];
376        }
377
378        if (!writer->writeRow(&row)) {
379          delete[] row;
380          return splashErrGeneric;
381        }
382      }
383      delete[] row;
384    }
385    break;
386   
387    case splashModeMono1:
388    {
389      unsigned char *row = new unsigned char[3 * width];
390      for (int y = 0; y < height; y++) {
391        // Convert into a PNG row
392        for (int x = 0; x < width; x++) {
393          getPixel(x, y, &row[3*x]);
394          row[3*x+1] = row[3*x];
395          row[3*x+2] = row[3*x];
396        }
397
398        if (!writer->writeRow(&row)) {
399          delete[] row;
400          return splashErrGeneric;
401        }
402      }
403      delete[] row;
404    }
405    break;
406   
407    default:
408    // can't happen
409    break;
410  }
411 
412  if (writer->close()) {
413    return splashErrGeneric;
414  }
415
416  return splashOk;
417}
Note: See TracBrowser for help on using the repository browser.