/* * cupsraster2ppm.c -- a converter to make rasterfiles usable to the rest of the world. * * cups raster files are unrelated to sun raster files. * * 2012-01-18, jw@suse.de * Distribute under GPL-2.0 */ #include #include // htonl #include "error.c" // from http://www.easysw.com/~mike/rasterview/rasterview-1.3.tar.gz #include "raster.c" // from http://www.easysw.com/~mike/rasterview/rasterview-1.3.tar.gz #if 0 # define endian_offset 0 // Big endian #else # define endian_offset 1 // Little endian #endif static void convert_rgb(); int main() { cups_raster_t *in = cupsRasterOpen(0, CUPS_RASTER_READ); if (!in) { fprintf(stderr, "cupsRasterOpen(stdin): not a cups rasterfile.\n"); exit(1); } cups_page_header2_t header; int ok = cupsRasterReadHeader2(in, &header); if (!ok) { fprintf(stderr, "cupsRasterReadHeader2(stdin) failed.\n"); exit(1); } printf((header.cupsNumColors == 1) ? "P4\n" : "P6\n"); printf("# HWResolution = {%d, %d}\n", header.HWResolution[0], header.HWResolution[1]); printf("# PageSize = {%d, %d}\n", header.PageSize[0], header.PageSize[1]); printf("# ImagingBoundingBox = {%d, %d, %d, %d}\n", header.ImagingBoundingBox[0], header.ImagingBoundingBox[1], header.ImagingBoundingBox[2], header.ImagingBoundingBox[3]); printf("# LeadingEdge = %d (0=CUPS_EDGE_TOP)\n", (int)header.LeadingEdge); printf("# cupsColorSpace = %d (1=CUPS_CSPACE_RGB)\n", (int)header.cupsColorSpace); printf("# cupsNumColors = %d\n", header.cupsNumColors); printf("# cupsBitsPerColor = %d\n", header.cupsBitsPerColor); // 8 printf("# cupsBitsPerPixel = %d\n", header.cupsBitsPerPixel); // 24 printf("# cupsWidth = %d\n", header.cupsWidth); printf("# cupsHeight = %d\n", header.cupsHeight); printf("# cupsBytesPerLine = %d\n", header.cupsBytesPerLine); printf("%d %d\n%d\n", header.cupsWidth, header.cupsHeight, (1< 0; x--) { if (bpp == 3) { putchar(*p++); // R putchar(*p++); // G putchar(*p++); // B } else { putchar(*p++); // V } } } return 0; } // taken from RasterDisplay.cxx static void convert_rgb( cups_page_header2_t *header, // I - Raster header */ unsigned char *line, // I - Raster line unsigned char *colors, // O - Original pixels unsigned char *pixels) // O - RGB pixels { int x, // X position in line w, // Width of line val; // Pixel value unsigned char *rptr, // Red pointer *gptr, // Green pointer *bptr, // Blue pointer bit; // Current bit w = header->cupsWidth; if (header->cupsColorOrder == CUPS_ORDER_CHUNKED) { // Chunky switch (header->cupsBitsPerColor) { case 1 : memset(pixels, 0, w * 3); for (x = w; x > 0; x -= 2, pixels += 6) { bit = *line++; *colors++ = bit >> 4; if (bit & 0x40) pixels[0] = 255; if (bit & 0x20) pixels[1] = 255; if (bit & 0x10) pixels[2] = 255; if (x > 1) { *colors++ = bit & 0x0f; if (bit & 0x04) pixels[3] = 255; if (bit & 0x02) pixels[4] = 255; if (bit & 0x01) pixels[5] = 255; } } break; case 2 : for (x = w; x > 0; x --) { *colors++ = bit = *line++; *pixels++ = 85 * ((bit & 0x30) >> 4); *pixels++ = 85 * ((bit & 0x0c) >> 2); *pixels++ = 85 * (bit & 0x03); } break; case 4 : memset(pixels, 0, w * 3); for (x = w; x > 0; x --, pixels += 3) { bit = *line++; *colors++ = bit; if (bit & 0x0f) pixels[0] += 17 * (bit & 0x0f); bit = *line++; *colors++ = bit; if (bit & 0xf0) pixels[1] += 17 * ((bit & 0xf0) >> 4); if (bit & 0x0f) pixels[2] += 17 * (bit & 0x0f); } break; case 8 : memcpy(colors, line, w * 3); memcpy(pixels, line, w * 3); break; case 16 : if (endian_offset) *colors++ = *line++; for (x = w; x > 0; x --) { *colors++ = *pixels++ = *line++; *colors++ = *line++; *colors++ = *pixels++ = *line++; *colors++ = *line++; *colors++ = *pixels++ = *line++; if (!endian_offset || x > 1) *colors++ = *line++; } break; } } else { // Banded int bytespercolor = (header->cupsBitsPerColor * header->cupsWidth + 7) / 8; rptr = line; gptr = line + bytespercolor; bptr = line + 2 * bytespercolor; switch (header->cupsBitsPerColor) { case 1 : memset(pixels, 0, w * 3); for (x = w, bit = 0x80; x > 0; x --, pixels += 3) { if (*rptr & bit) { *colors++ = 1; pixels[0] = 255; } else colors ++; if (*gptr & bit) { *colors++ = 1; pixels[1] = 255; } else colors ++; if (*bptr & bit) { *colors++ = 1; pixels[2] = 255; } else colors ++; if (bit > 1) bit >>= 1; else { bit = 0x80; rptr ++; gptr ++; bptr ++; } } break; case 2 : for (x = 0; x < w; x ++) { switch (x & 3) { case 0 : *colors++ = val = (*rptr & 0xc0) >> 6; *pixels++ = 85 * val; *colors++ = val = (*gptr & 0xc0) >> 6; *pixels++ = 85 * val; *colors++ = val = (*bptr & 0xc0) >> 6; *pixels++ = 85 * val; break; case 1 : *colors++ = val = (*rptr & 0x30) >> 4; *pixels++ = 85 * val; *colors++ = val = (*gptr & 0x30) >> 4; *pixels++ = 85 * val; *colors++ = val = (*bptr & 0x30) >> 4; *pixels++ = 85 * val; break; case 2 : *colors++ = val = (*rptr & 0x0c) >> 2; *pixels++ = 85 * val; *colors++ = val = (*gptr & 0x0c) >> 2; *pixels++ = 85 * val; *colors++ = val = (*bptr & 0x0c) >> 2; *pixels++ = 85 * val; break; case 3 : *colors++ = val = *rptr & 0x03; *pixels++ = 85 * val; *colors++ = val = *gptr & 0x03; *pixels++ = 85 * val; *colors++ = val = *bptr & 0x03; *pixels++ = 85 * val; rptr ++; gptr ++; bptr ++; break; } } break; case 4 : for (x = 0; x < w; x ++) { switch (x & 1) { case 0 : *colors++ = val = (*rptr & 0xf0) >> 4; *pixels++ = 17 * val; *colors++ = val = (*gptr & 0xf0) >> 4; *pixels++ = 17 * val; *colors++ = val = (*bptr & 0xf0) >> 4; *pixels++ = 17 * val; break; case 1 : *colors++ = val = *rptr & 0x0f; *pixels++ = 17 * val; *colors++ = val = *gptr & 0x0f; *pixels++ = 17 * val; *colors++ = val = *bptr & 0x0f; *pixels++ = 17 * val; rptr ++; gptr ++; bptr ++; break; } } break; case 8 : for (x = w; x > 0; x --) { *colors++ = *pixels++ = *rptr++; *colors++ = *pixels++ = *gptr++; *colors++ = *pixels++ = *bptr++; } break; case 16 : if (endian_offset) { for (x = w; x > 0; x --) { *colors++ = *rptr++; *colors++ = *pixels++ = *rptr++; *colors++ = *gptr++; *colors++ = *pixels++ = *gptr++; *colors++ = *bptr++; *colors++ = *pixels++ = *bptr++; } } else { for (x = w; x > 0; x --) { *colors++ = *pixels++ = *rptr++; *colors++ = *rptr++; *colors++ = *pixels++ = *gptr++; *colors++ = *gptr++; *colors++ = *pixels++ = *bptr++; *colors++ = *bptr++; } } break; } } }