static void makeNewXel(xel * const outputXelP, xel const curXel, xel const prevXel, double const fracnew0, double const omfracnew0, int const format) { /*---------------------------------------------------------------------------- Create an output xel as *outputXel, which is part curXel and part prevXel, the part given by the fractions omfracnew0 and fracnew0, respectively. These fraction values are the numerator of a fraction whose denominator is SCALE. The format of the pixel is 'format'. -----------------------------------------------------------------------------*/ switch ( PNM_FORMAT_TYPE(format) ) { case PPM_TYPE: PPM_ASSIGN( *outputXelP, ( fracnew0 * PPM_GETR(prevXel) + omfracnew0 * PPM_GETR(curXel) + HALFSCALE ) / SCALE, ( fracnew0 * PPM_GETG(prevXel) + omfracnew0 * PPM_GETG(curXel) + HALFSCALE ) / SCALE, ( fracnew0 * PPM_GETB(prevXel) + omfracnew0 * PPM_GETB(curXel) + HALFSCALE ) / SCALE ); break; default: PNM_ASSIGN1( *outputXelP, ( fracnew0 * PNM_GET1(prevXel) + omfracnew0 * PNM_GET1(curXel) + HALFSCALE ) / SCALE ); break; } }
void pnm_writepnmrow(FILE * const fileP, xel * const xelrow, int const cols, xelval const maxval, int const format, int const forceplain) { bool const plainFormat = forceplain || pm_plain_output; switch (PNM_FORMAT_TYPE(format)) { case PPM_TYPE: ppm_writeppmrow(fileP, (pixel*) xelrow, cols, (pixval) maxval, plainFormat); break; case PGM_TYPE: { gray* grayrow; unsigned int col; grayrow = pgm_allocrow(cols); for (col = 0; col < cols; ++col) grayrow[col] = PNM_GET1(xelrow[col]); pgm_writepgmrow(fileP, grayrow, cols, (gray) maxval, plainFormat); pgm_freerow( grayrow ); } break; case PBM_TYPE: { bit* bitrow; unsigned int col; bitrow = pbm_allocrow(cols); for (col = 0; col < cols; ++col) bitrow[col] = PNM_GET1(xelrow[col]) == 0 ? PBM_BLACK : PBM_WHITE; pbm_writepbmrow(fileP, bitrow, cols, plainFormat); pbm_freerow(bitrow); } break; default: pm_error("invalid format argument received by pnm_writepnmrow(): %d" "PNM_FORMAT_TYPE(format) must be %d, %d, or %d", format, PBM_TYPE, PGM_TYPE, PPM_TYPE); } }
static void print_bw_data(xel **pnm, int cols, int rows) { int i, j, k, l; unsigned char data; for (i = 0, k = 0, l = 0, data = 0; i < rows; i++) { for (j = 0; j < cols; j++, l = (l+1) % 8) { if (PNM_GET1(pnm[i][j])) data |= bitmask[l]; if (l == 7) { if (k == 0) printf(" "); printf(" 0x%02x, ", data); if (k == 11) putchar('\n'); k = (k+1) % 12; data = 0; } } if (l != 0) { if (k == 0) printf(" "); printf(" 0x%02x, ", data); if (k == 11) putchar('\n'); k = (k+1) % 12; data = 0; } } if (k != 0) putchar('\n'); }
static void writepbmrow(FILE * const fileP, const xel * const xelrow, unsigned int const cols, bool const plainFormat) { jmp_buf jmpbuf; jmp_buf * origJmpbufP; bit * bitrow; bitrow = pbm_allocrow(cols); if (setjmp(jmpbuf) != 0) { pbm_freerow(bitrow); pm_setjmpbuf(origJmpbufP); pm_longjmp(); } else { unsigned int col; pm_setjmpbufsave(&jmpbuf, &origJmpbufP); for (col = 0; col < cols; ++col) bitrow[col] = PNM_GET1(xelrow[col]) == 0 ? PBM_BLACK : PBM_WHITE; pbm_writepbmrow(fileP, bitrow, cols, plainFormat); pm_setjmpbuf(origJmpbufP); } pbm_freerow(bitrow); }
static void writepgmrow(FILE * const fileP, const xel * const xelrow, unsigned int const cols, xelval const maxval, int const format, bool const plainFormat) { jmp_buf jmpbuf; jmp_buf * origJmpbufP; gray * grayrow; grayrow = pgm_allocrow(cols); if (setjmp(jmpbuf) != 0) { pgm_freerow(grayrow); pm_setjmpbuf(origJmpbufP); pm_longjmp(); } else { unsigned int col; pm_setjmpbufsave(&jmpbuf, &origJmpbufP); for (col = 0; col < cols; ++col) grayrow[col] = PNM_GET1(xelrow[col]); pgm_writepgmrow(fileP, grayrow, cols, (gray) maxval, plainFormat); pm_setjmpbuf(origJmpbufP); } pgm_freerow(grayrow); }
static void remap(xel ** const xels, unsigned int const cols, unsigned int const rows, xelval const maxval, int const format, bool const monoOnly, const gray * const lumamap) { /*---------------------------------------------------------------------------- Update the array 'xels' to have the new intensities. -----------------------------------------------------------------------------*/ switch (PNM_FORMAT_TYPE(format)) { case PPM_TYPE: { unsigned int row; for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) { xel const thisXel = xels[row][col]; if (monoOnly && PPM_ISGRAY(thisXel)) { /* Leave this pixel alone */ } else { struct hsv hsv; xelval iv; hsv = ppm_hsv_from_color(thisXel, maxval); iv = MIN(maxval, ROUNDU(hsv.v * maxval)); hsv.v = MIN(1.0, ((double) lumamap[iv]) / ((double) maxval)); xels[row][col] = ppm_color_from_hsv(hsv, maxval); } } } } break; case PBM_TYPE: case PGM_TYPE: { unsigned int row; for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) PNM_ASSIGN1(xels[row][col], lumamap[PNM_GET1(xels[row][col])]); } } break; } }
static void print_grey256_data(xel **pnm, int cols, int rows, int maxval) { int i, j, k; for (i = 0, k = 0; i < rows; i++) for (j = 0; j < cols; j++, k = (k+1) % 12) { if (k == 0) printf(" "); printf(" 0x%02x,", PNM_GET1(pnm[i][j])*(255+maxval/2)/maxval); if (k == 11) putchar('\n'); } if (k != 0) putchar('\n'); }
static void computeLuminosityHistogram(xel * const * const xels, unsigned int const rows, unsigned int const cols, xelval const maxval, int const format, bool const monoOnly, unsigned int ** const lumahistP, xelval * const lminP, xelval * const lmaxP, unsigned int * const pixelCountP) { /*---------------------------------------------------------------------------- Scan the image and build the luminosity histogram. If the input is a PPM, we calculate the luminosity of each pixel from its RGB components. -----------------------------------------------------------------------------*/ xelval lmin, lmax; unsigned int pixelCount; unsigned int * lumahist; MALLOCARRAY(lumahist, maxval + 1); if (lumahist == NULL) pm_error("Out of storage allocating array for %u histogram elements", maxval + 1); { unsigned int i; /* Initialize histogram to zeroes everywhere */ for (i = 0; i <= maxval; ++i) lumahist[i] = 0; } lmin = maxval; /* initial value */ lmax = 0; /* initial value */ switch (PNM_FORMAT_TYPE(format)) { case PGM_TYPE: case PBM_TYPE: { /* Compute intensity histogram */ unsigned int row; pixelCount = rows * cols; for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) { xelval const l = PNM_GET1(xels[row][col]); lmin = MIN(lmin, l); lmax = MAX(lmax, l); ++lumahist[l]; } } } break; case PPM_TYPE: { unsigned int row; for (row = 0, pixelCount = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) { xel const thisXel = xels[row][col]; if (!monoOnly || PPM_ISGRAY(thisXel)) { xelval const l = PPM_LUMIN(thisXel); lmin = MIN(lmin, l); lmax = MAX(lmax, l); ++lumahist[l]; ++pixelCount; } } } } break; default: pm_error("invalid input format format"); } *lumahistP = lumahist; *pixelCountP = pixelCount; *lminP = lmin; *lmaxP = lmax; }
/*----------------------------------------------------------------------------- * Write the rle data portion of the file. */ static void write_rle_data() { register int x; register int scan; register xel *xelrow, *pP; rle_pixel ***scanlines, **scanline; /* * Allocate some memory. */ /*xelrow = pnm_allowcrow(width);*/ xelrow = (xel*) pm_allocrow( width, sizeof(xel) ); MALLOCARRAY(scanlines, height); RLE_CHECK_ALLOC( hdr.cmd, scanlines, "scanline pointers" ); for ( scan = 0; scan < height; scan++ ) RLE_CHECK_ALLOC( hdr.cmd, (rle_row_alloc(&hdr, &scanlines[scan]) >= 0), "pixel memory" ); /* * Loop through the pnm files image window, read data and flip vertically. */ switch (format) { case PBM_FORMAT: case RPBM_FORMAT: for (scan = 0; scan < height; scan++) { scanline = scanlines[height - scan - 1]; pnm_readpnmrow(fp, xelrow, width, maxval, format); for (x = 0, pP = xelrow; x < width; x++, pP++) { scanline[RLE_RED][x] = (PNM_GET1(*pP) ? 255 : 0); if (do_alpha) { scanline[RLE_ALPHA][x] = scanline[RLE_RED][x]; } } } break; case PGM_FORMAT: case RPGM_FORMAT: for (scan = 0; scan < height; scan++) { scanline = scanlines[height - scan - 1]; pnm_readpnmrow(fp, xelrow, width, maxval, format); for (x = 0, pP = xelrow; x < width; x++, pP++) { scanline[RLE_RED][x] = PNM_GET1(*pP); if (do_alpha) { scanline[RLE_ALPHA][x] = (scanline[RLE_RED][x] ? 255 : 0); } } } break; case PPM_FORMAT: case RPPM_FORMAT: for (scan = 0; scan < height; scan++) { scanline = scanlines[height - scan - 1]; pnm_readpnmrow(fp, xelrow, width, maxval, format); for (x = 0, pP = xelrow; x < width; x++, pP++) { scanline[RLE_RED][x] = PPM_GETR(*pP); scanline[RLE_GREEN][x] = PPM_GETG(*pP); scanline[RLE_BLUE][x] = PPM_GETB(*pP); if (do_alpha) { scanline[RLE_ALPHA][x] = (scanline[RLE_RED][x] || scanline[RLE_GREEN][x] || scanline[RLE_BLUE][x] ? 255 : 0); } } } break; } /* * Write out data in URT order (bottom to top). */ for ( scan = 0; scan < height; scan++ ) { rle_putrow(scanlines[scan], width, &hdr); rle_row_free( &hdr, scanlines[scan] ); } free( scanlines ); VPRINTF(stderr, "Done -- write eof to RLE data.\n"); rle_puteof(&hdr); }