| //======================================================================== |
| // |
| // SplashBitmap.cc |
| // |
| //======================================================================== |
| |
| #include <config.h> |
| |
| #ifdef USE_GCC_PRAGMAS |
| #pragma implementation |
| #endif |
| |
| #include <stdio.h> |
| #include "goo/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: |
| rowSize = (width + 7) >> 3; |
| break; |
| case splashModeMono8: |
| rowSize = width; |
| break; |
| case splashModeRGB8: |
| case splashModeBGR8: |
| rowSize = width * 3; |
| break; |
| case splashModeXBGR8: |
| rowSize = width * 4; |
| break; |
| #if SPLASH_CMYK |
| case splashModeCMYK8: |
| rowSize = width * 4; |
| break; |
| #endif |
| } |
| rowSize += rowPad - 1; |
| rowSize -= rowSize % rowPad; |
| data = (SplashColorPtr)gmalloc(rowSize * height); |
| if (!topDown) { |
| data += (height - 1) * rowSize; |
| rowSize = -rowSize; |
| } |
| if (alphaA) { |
| alpha = (Guchar *)gmalloc(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; |
| SplashError e; |
| |
| if (!(f = fopen(fileName, "wb"))) { |
| return splashErrOpenFile; |
| } |
| |
| e = this->writePNMFile(f); |
| |
| fclose(f); |
| return e; |
| } |
| |
| |
| SplashError SplashBitmap::writePNMFile(FILE *f) { |
| SplashColorPtr row, p; |
| int x, y; |
| |
| 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 splashModeXBGR8: |
| 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 += 4; |
| } |
| 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 |
| } |
| 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 splashModeXBGR8: |
| p = &data[y * rowSize + 4 * x]; |
| pixel[0] = p[2]; |
| pixel[1] = p[1]; |
| pixel[2] = p[0]; |
| pixel[3] = p[3]; |
| 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]; |
| } |