~ubuntu-branches/ubuntu/natty/luatex/natty

« back to all changes in this revision

Viewing changes to source/libs/poppler/poppler-0.12.4/splash/SplashBitmap.cc

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2010-12-13 23:22:59 UTC
  • mfrom: (0.2.1) (1.5.4) (4.3.12 experimental)
  • Revision ID: package-import@ubuntu.com-20101213232259-nqq2mq5z5x6qldw3
Tags: 0.65.0-1
* new upstream release
* ship two source packages as they are distributed by upstream, only
  renamed to match source package requirements. Fix debian/rules
  to install the manual pdf from the right place

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 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
//
 
18
// To see a description of the changes please see the Changelog file that
 
19
// came with your tarball or type make ChangeLog if you are building from git
 
20
//
 
21
//========================================================================
 
22
 
 
23
#include <config.h>
 
24
 
 
25
#ifdef USE_GCC_PRAGMAS
 
26
#pragma implementation
 
27
#endif
 
28
 
 
29
#include <stdio.h>
 
30
#include <stdlib.h>
 
31
#include <limits.h>
 
32
#include "goo/gmem.h"
 
33
#include "SplashErrorCodes.h"
 
34
#include "SplashBitmap.h"
 
35
#include "poppler/Error.h"
 
36
#include "PNGWriter.h"
 
37
 
 
38
//------------------------------------------------------------------------
 
39
// SplashBitmap
 
40
//------------------------------------------------------------------------
 
41
 
 
42
SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
 
43
                           SplashColorMode modeA, GBool alphaA,
 
44
                           GBool topDown) {
 
45
  width = widthA;
 
46
  height = heightA;
 
47
  mode = modeA;
 
48
  switch (mode) {
 
49
  case splashModeMono1:
 
50
    if (width > 0) {
 
51
      rowSize = (width + 7) >> 3;
 
52
    } else {
 
53
      rowSize = -1;
 
54
    }
 
55
    break;
 
56
  case splashModeMono8:
 
57
    if (width > 0) {
 
58
      rowSize = width;
 
59
    } else {
 
60
      rowSize = -1;
 
61
    }
 
62
    break;
 
63
  case splashModeRGB8:
 
64
  case splashModeBGR8:
 
65
    if (width > 0 && width <= INT_MAX / 3) {
 
66
      rowSize = width * 3;
 
67
    } else {
 
68
      rowSize = -1;
 
69
    }
 
70
    break;
 
71
  case splashModeXBGR8:
 
72
    if (width > 0 && width <= INT_MAX / 4) {
 
73
      rowSize = width * 4;
 
74
    } else {
 
75
      rowSize = -1;
 
76
    }
 
77
    break;
 
78
#if SPLASH_CMYK
 
79
  case splashModeCMYK8:
 
80
    if (width > 0 && width <= INT_MAX / 4) {
 
81
      rowSize = width * 4;
 
82
    } else {
 
83
      rowSize = -1;
 
84
    }
 
85
    break;
 
86
#endif
 
87
  }
 
88
  if (rowSize > 0) {
 
89
    rowSize += rowPad - 1;
 
90
    rowSize -= rowSize % rowPad;
 
91
  }
 
92
  data = (SplashColorPtr)gmallocn(rowSize, height);
 
93
  if (!topDown) {
 
94
    data += (height - 1) * rowSize;
 
95
    rowSize = -rowSize;
 
96
  }
 
97
  if (alphaA) {
 
98
    alpha = (Guchar *)gmallocn(width, height);
 
99
  } else {
 
100
    alpha = NULL;
 
101
  }
 
102
}
 
103
 
 
104
 
 
105
SplashBitmap::~SplashBitmap() {
 
106
  if (rowSize < 0) {
 
107
    gfree(data + (height - 1) * rowSize);
 
108
  } else {
 
109
    gfree(data);
 
110
  }
 
111
  gfree(alpha);
 
112
}
 
113
 
 
114
 
 
115
SplashError SplashBitmap::writePNMFile(char *fileName) {
 
116
  FILE *f;
 
117
  SplashError e;
 
118
 
 
119
  if (!(f = fopen(fileName, "wb"))) {
 
120
    return splashErrOpenFile;
 
121
  }
 
122
 
 
123
  e = this->writePNMFile(f);
 
124
  
 
125
  fclose(f);
 
126
  return e;
 
127
}
 
128
 
 
129
 
 
130
SplashError SplashBitmap::writePNMFile(FILE *f) {
 
131
  SplashColorPtr row, p;
 
132
  int x, y;
 
133
 
 
134
  switch (mode) {
 
135
 
 
136
  case splashModeMono1:
 
137
    fprintf(f, "P4\n%d %d\n", width, height);
 
138
    row = data;
 
139
    for (y = 0; y < height; ++y) {
 
140
      p = row;
 
141
      for (x = 0; x < width; x += 8) {
 
142
        fputc(*p ^ 0xff, f);
 
143
        ++p;
 
144
      }
 
145
      row += rowSize;
 
146
    }
 
147
    break;
 
148
 
 
149
  case splashModeMono8:
 
150
    fprintf(f, "P5\n%d %d\n255\n", width, height);
 
151
    row = data;
 
152
    for (y = 0; y < height; ++y) {
 
153
      p = row;
 
154
      for (x = 0; x < width; ++x) {
 
155
        fputc(*p, f);
 
156
        ++p;
 
157
      }
 
158
      row += rowSize;
 
159
    }
 
160
    break;
 
161
 
 
162
  case splashModeRGB8:
 
163
    fprintf(f, "P6\n%d %d\n255\n", width, height);
 
164
    row = data;
 
165
    for (y = 0; y < height; ++y) {
 
166
      p = row;
 
167
      for (x = 0; x < width; ++x) {
 
168
        fputc(splashRGB8R(p), f);
 
169
        fputc(splashRGB8G(p), f);
 
170
        fputc(splashRGB8B(p), f);
 
171
        p += 3;
 
172
      }
 
173
      row += rowSize;
 
174
    }
 
175
    break;
 
176
 
 
177
  case splashModeXBGR8:
 
178
    fprintf(f, "P6\n%d %d\n255\n", width, height);
 
179
    row = data;
 
180
    for (y = 0; y < height; ++y) {
 
181
      p = row;
 
182
      for (x = 0; x < width; ++x) {
 
183
        fputc(splashBGR8R(p), f);
 
184
        fputc(splashBGR8G(p), f);
 
185
        fputc(splashBGR8B(p), f);
 
186
        p += 4;
 
187
      }
 
188
      row += rowSize;
 
189
    }
 
190
    break;
 
191
 
 
192
 
 
193
  case splashModeBGR8:
 
194
    fprintf(f, "P6\n%d %d\n255\n", width, height);
 
195
    row = data;
 
196
    for (y = 0; y < height; ++y) {
 
197
      p = row;
 
198
      for (x = 0; x < width; ++x) {
 
199
        fputc(splashBGR8R(p), f);
 
200
        fputc(splashBGR8G(p), f);
 
201
        fputc(splashBGR8B(p), f);
 
202
        p += 3;
 
203
      }
 
204
      row += rowSize;
 
205
    }
 
206
    break;
 
207
 
 
208
#if SPLASH_CMYK
 
209
  case splashModeCMYK8:
 
210
    // PNM doesn't support CMYK
 
211
    error(-1, "unsupported SplashBitmap mode");
 
212
    return splashErrGeneric;
 
213
    break;
 
214
#endif
 
215
  }
 
216
  return splashOk;
 
217
}
 
218
 
 
219
 
 
220
void SplashBitmap::getPixel(int x, int y, SplashColorPtr pixel) {
 
221
  SplashColorPtr p;
 
222
 
 
223
  if (y < 0 || y >= height || x < 0 || x >= width) {
 
224
    return;
 
225
  }
 
226
  switch (mode) {
 
227
  case splashModeMono1:
 
228
    p = &data[y * rowSize + (x >> 3)];
 
229
    pixel[0] = (p[0] & (0x80 >> (x & 7))) ? 0xff : 0x00;
 
230
    break;
 
231
  case splashModeMono8:
 
232
    p = &data[y * rowSize + x];
 
233
    pixel[0] = p[0];
 
234
    break;
 
235
  case splashModeRGB8:
 
236
    p = &data[y * rowSize + 3 * x];
 
237
    pixel[0] = p[0];
 
238
    pixel[1] = p[1];
 
239
    pixel[2] = p[2];
 
240
    break;
 
241
  case splashModeXBGR8:
 
242
    p = &data[y * rowSize + 4 * x];
 
243
    pixel[0] = p[2];
 
244
    pixel[1] = p[1];
 
245
    pixel[2] = p[0];
 
246
    pixel[3] = p[3];
 
247
    break;
 
248
  case splashModeBGR8:
 
249
    p = &data[y * rowSize + 3 * x];
 
250
    pixel[0] = p[2];
 
251
    pixel[1] = p[1];
 
252
    pixel[2] = p[0];
 
253
    break;
 
254
#if SPLASH_CMYK
 
255
  case splashModeCMYK8:
 
256
    p = &data[y * rowSize + 4 * x];
 
257
    pixel[0] = p[0];
 
258
    pixel[1] = p[1];
 
259
    pixel[2] = p[2];
 
260
    pixel[3] = p[3];
 
261
    break;
 
262
#endif
 
263
  }
 
264
}
 
265
 
 
266
Guchar SplashBitmap::getAlpha(int x, int y) {
 
267
  return alpha[y * width + x];
 
268
}
 
269
 
 
270
SplashError SplashBitmap::writePNGFile(char *fileName) {
 
271
  FILE *f;
 
272
  SplashError e;
 
273
 
 
274
  if (!(f = fopen(fileName, "wb"))) {
 
275
    return splashErrOpenFile;
 
276
  }
 
277
 
 
278
  e = writePNGFile(f);
 
279
  
 
280
  fclose(f);
 
281
  return e;
 
282
}
 
283
 
 
284
SplashError SplashBitmap::writePNGFile(FILE *f) {
 
285
#ifndef ENABLE_LIBPNG
 
286
  error(-1, "PNG support not compiled in");
 
287
  return splashErrGeneric;
 
288
#else
 
289
  if (mode != splashModeRGB8 && mode != splashModeMono8 && mode != splashModeMono1) {
 
290
    error(-1, "unsupported SplashBitmap mode");
 
291
    return splashErrGeneric;
 
292
  }
 
293
 
 
294
  PNGWriter *writer = new PNGWriter();
 
295
  if (!writer->init(f, width, height)) {
 
296
    delete writer;
 
297
    return splashErrGeneric;
 
298
  }
 
299
 
 
300
  switch (mode) {
 
301
    case splashModeRGB8:
 
302
    {
 
303
      SplashColorPtr row;
 
304
      png_bytep *row_pointers = new png_bytep[height];
 
305
      row = data;
 
306
 
 
307
      for (int y = 0; y < height; ++y) {
 
308
        row_pointers[y] = row;
 
309
        row += rowSize;
 
310
      }
 
311
      if (!writer->writePointers(row_pointers)) {
 
312
        delete[] row_pointers;
 
313
        delete writer;
 
314
        return splashErrGeneric;
 
315
      }
 
316
      delete[] row_pointers;
 
317
    }
 
318
    break;
 
319
    
 
320
    case splashModeMono8:
 
321
    {
 
322
      png_byte *row = new png_byte[3 * width];
 
323
      for (int y = 0; y < height; y++) {
 
324
        // Convert into a PNG row
 
325
        for (int x = 0; x < width; x++) {
 
326
          row[3*x] = data[y * rowSize + x];
 
327
          row[3*x+1] = data[y * rowSize + x];
 
328
          row[3*x+2] = data[y * rowSize + x];
 
329
        }
 
330
 
 
331
        if (!writer->writeRow(&row)) {
 
332
          delete[] row;
 
333
          delete writer;
 
334
          return splashErrGeneric;
 
335
        }
 
336
      }
 
337
      delete[] row;
 
338
    }
 
339
    break;
 
340
    
 
341
    case splashModeMono1:
 
342
    {
 
343
      png_byte *row = new png_byte[3 * width];
 
344
      for (int y = 0; y < height; y++) {
 
345
        // Convert into a PNG row
 
346
        for (int x = 0; x < width; x++) {
 
347
          getPixel(x, y, &row[3*x]);
 
348
          row[3*x+1] = row[3*x];
 
349
          row[3*x+2] = row[3*x];
 
350
        }
 
351
 
 
352
        if (!writer->writeRow(&row)) {
 
353
          delete[] row;
 
354
          delete writer;
 
355
          return splashErrGeneric;
 
356
        }
 
357
      }
 
358
      delete[] row;
 
359
    }
 
360
    break;
 
361
    
 
362
    default:
 
363
    // can't happen
 
364
    break;
 
365
  }
 
366
  
 
367
  if (writer->close()) {
 
368
    delete writer;
 
369
    return splashErrGeneric;
 
370
  }
 
371
 
 
372
  delete writer;
 
373
 
 
374
  return splashOk;
 
375
#endif
 
376
}