1
//========================================================================
5
//========================================================================
7
//========================================================================
9
// Modified under the Poppler project - http://poppler.freedesktop.org
11
// All changes made under the Poppler project to this file are licensed
12
// under GPL version 2 or later
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>
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
21
//========================================================================
25
#ifdef USE_GCC_PRAGMAS
26
#pragma implementation
33
#include "SplashErrorCodes.h"
34
#include "SplashBitmap.h"
35
#include "poppler/Error.h"
36
#include "PNGWriter.h"
38
//------------------------------------------------------------------------
40
//------------------------------------------------------------------------
42
SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
43
SplashColorMode modeA, GBool alphaA,
51
rowSize = (width + 7) >> 3;
65
if (width > 0 && width <= INT_MAX / 3) {
72
if (width > 0 && width <= INT_MAX / 4) {
80
if (width > 0 && width <= INT_MAX / 4) {
89
rowSize += rowPad - 1;
90
rowSize -= rowSize % rowPad;
92
data = (SplashColorPtr)gmallocn(rowSize, height);
94
data += (height - 1) * rowSize;
98
alpha = (Guchar *)gmallocn(width, height);
105
SplashBitmap::~SplashBitmap() {
107
gfree(data + (height - 1) * rowSize);
115
SplashError SplashBitmap::writePNMFile(char *fileName) {
119
if (!(f = fopen(fileName, "wb"))) {
120
return splashErrOpenFile;
123
e = this->writePNMFile(f);
130
SplashError SplashBitmap::writePNMFile(FILE *f) {
131
SplashColorPtr row, p;
136
case splashModeMono1:
137
fprintf(f, "P4\n%d %d\n", width, height);
139
for (y = 0; y < height; ++y) {
141
for (x = 0; x < width; x += 8) {
149
case splashModeMono8:
150
fprintf(f, "P5\n%d %d\n255\n", width, height);
152
for (y = 0; y < height; ++y) {
154
for (x = 0; x < width; ++x) {
163
fprintf(f, "P6\n%d %d\n255\n", width, height);
165
for (y = 0; y < height; ++y) {
167
for (x = 0; x < width; ++x) {
168
fputc(splashRGB8R(p), f);
169
fputc(splashRGB8G(p), f);
170
fputc(splashRGB8B(p), f);
177
case splashModeXBGR8:
178
fprintf(f, "P6\n%d %d\n255\n", width, height);
180
for (y = 0; y < height; ++y) {
182
for (x = 0; x < width; ++x) {
183
fputc(splashBGR8R(p), f);
184
fputc(splashBGR8G(p), f);
185
fputc(splashBGR8B(p), f);
194
fprintf(f, "P6\n%d %d\n255\n", width, height);
196
for (y = 0; y < height; ++y) {
198
for (x = 0; x < width; ++x) {
199
fputc(splashBGR8R(p), f);
200
fputc(splashBGR8G(p), f);
201
fputc(splashBGR8B(p), f);
209
case splashModeCMYK8:
210
// PNM doesn't support CMYK
211
error(-1, "unsupported SplashBitmap mode");
212
return splashErrGeneric;
220
void SplashBitmap::getPixel(int x, int y, SplashColorPtr pixel) {
223
if (y < 0 || y >= height || x < 0 || x >= width) {
227
case splashModeMono1:
228
p = &data[y * rowSize + (x >> 3)];
229
pixel[0] = (p[0] & (0x80 >> (x & 7))) ? 0xff : 0x00;
231
case splashModeMono8:
232
p = &data[y * rowSize + x];
236
p = &data[y * rowSize + 3 * x];
241
case splashModeXBGR8:
242
p = &data[y * rowSize + 4 * x];
249
p = &data[y * rowSize + 3 * x];
255
case splashModeCMYK8:
256
p = &data[y * rowSize + 4 * x];
266
Guchar SplashBitmap::getAlpha(int x, int y) {
267
return alpha[y * width + x];
270
SplashError SplashBitmap::writePNGFile(char *fileName) {
274
if (!(f = fopen(fileName, "wb"))) {
275
return splashErrOpenFile;
284
SplashError SplashBitmap::writePNGFile(FILE *f) {
285
#ifndef ENABLE_LIBPNG
286
error(-1, "PNG support not compiled in");
287
return splashErrGeneric;
289
if (mode != splashModeRGB8 && mode != splashModeMono8 && mode != splashModeMono1) {
290
error(-1, "unsupported SplashBitmap mode");
291
return splashErrGeneric;
294
PNGWriter *writer = new PNGWriter();
295
if (!writer->init(f, width, height)) {
297
return splashErrGeneric;
304
png_bytep *row_pointers = new png_bytep[height];
307
for (int y = 0; y < height; ++y) {
308
row_pointers[y] = row;
311
if (!writer->writePointers(row_pointers)) {
312
delete[] row_pointers;
314
return splashErrGeneric;
316
delete[] row_pointers;
320
case splashModeMono8:
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];
331
if (!writer->writeRow(&row)) {
334
return splashErrGeneric;
341
case splashModeMono1:
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];
352
if (!writer->writeRow(&row)) {
355
return splashErrGeneric;
367
if (writer->close()) {
369
return splashErrGeneric;