You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegraphics/kpdf/xpdf/splash/SplashBitmap.cpp

208 lines
4.1 KiB

//========================================================================
//
// SplashBitmap.cpp
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#include <limits.h>
#include "gmem.h"
#include "SplashErrorCodes.h"
#include "SplashBitmap.h"
//------------------------------------------------------------------------
// SplashBitmap
//------------------------------------------------------------------------
SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
SplashColorMode modeA, GBool alphaA,
GBool topDown) {
width = widthA;
height = heightA;
mode = modeA;
switch (mode) {
case splashModeMono1:
if (width > 0) {
rowSize = (width + 7) >> 3;
} else {
rowSize = -1;
}
break;
case splashModeMono8:
if (width > 0) {
rowSize = width;
} else {
rowSize = -1;
}
break;
case splashModeRGB8:
case splashModeBGR8:
if (width > 0 && width <= INT_MAX / 3) {
rowSize = width * 3;
} else {
rowSize = -1;
}
break;
#if SPLASH_CMYK
case splashModeCMYK8:
if (width > 0 && width <= INT_MAX / 4) {
rowSize = width * 4;
} else {
rowSize = -1;
}
break;
#endif
}
if (rowSize > 0) {
rowSize += rowPad - 1;
rowSize -= rowSize % rowPad;
}
data = (SplashColorPtr)gmallocn(height, rowSize);
if (!topDown) {
data += (height - 1) * rowSize;
rowSize = -rowSize;
}
if (alphaA) {
alpha = (Guchar *)gmallocn(width, height);
} else {
alpha = NULL;
}
}
SplashBitmap::~SplashBitmap() {
if (rowSize < 0) {
gfree(data + (height - 1) * rowSize);
} else {
gfree(data);
}
gfree(alpha);
}
SplashError SplashBitmap::writePNMFile(char *fileName) {
FILE *f;
SplashColorPtr row, p;
int x, y;
if (!(f = fopen(fileName, "wb"))) {
return splashErrOpenFile;
}
switch (mode) {
case splashModeMono1:
fprintf(f, "P4\n%d %d\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; x += 8) {
fputc(*p ^ 0xff, f);
++p;
}
row += rowSize;
}
break;
case splashModeMono8:
fprintf(f, "P5\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(*p, f);
++p;
}
row += rowSize;
}
break;
case splashModeRGB8:
fprintf(f, "P6\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(splashRGB8R(p), f);
fputc(splashRGB8G(p), f);
fputc(splashRGB8B(p), f);
p += 3;
}
row += rowSize;
}
break;
case splashModeBGR8:
fprintf(f, "P6\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(splashBGR8R(p), f);
fputc(splashBGR8G(p), f);
fputc(splashBGR8B(p), f);
p += 3;
}
row += rowSize;
}
break;
#if SPLASH_CMYK
case splashModeCMYK8:
// PNM doesn't support CMYK
break;
#endif
}
fclose(f);
return splashOk;
}
void SplashBitmap::getPixel(int x, int y, SplashColorPtr pixel) {
SplashColorPtr p;
if (y < 0 || y >= height || x < 0 || x >= width) {
return;
}
switch (mode) {
case splashModeMono1:
p = &data[y * rowSize + (x >> 3)];
pixel[0] = (p[0] & (0x80 >> (x & 7))) ? 0xff : 0x00;
break;
case splashModeMono8:
p = &data[y * rowSize + x];
pixel[0] = p[0];
break;
case splashModeRGB8:
p = &data[y * rowSize + 3 * x];
pixel[0] = p[0];
pixel[1] = p[1];
pixel[2] = p[2];
break;
case splashModeBGR8:
p = &data[y * rowSize + 3 * x];
pixel[0] = p[2];
pixel[1] = p[1];
pixel[2] = p[0];
break;
#if SPLASH_CMYK
case splashModeCMYK8:
p = &data[y * rowSize + 4 * x];
pixel[0] = p[0];
pixel[1] = p[1];
pixel[2] = p[2];
pixel[3] = p[3];
break;
#endif
}
}
Guchar SplashBitmap::getAlpha(int x, int y) {
return alpha[y * width + x];
}