From 1fd361a1ea06e44286c213ca1f814f49306fdc43 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 19 Aug 2006 03:12:28 +0000 Subject: Create Subversion repository git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- lib/libppm2.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 lib/libppm2.c (limited to 'lib/libppm2.c') diff --git a/lib/libppm2.c b/lib/libppm2.c new file mode 100644 index 00000000..52c4ab16 --- /dev/null +++ b/lib/libppm2.c @@ -0,0 +1,208 @@ +/* libppm2.c - ppm utility library part 2 +** +** Copyright (C) 1989 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include +#include + + +#include "pm_c_util.h" +#include "mallocvar.h" +#include "ppm.h" +#include "libppm.h" + +void +ppm_writeppminit(FILE* const fileP, + int const cols, + int const rows, + pixval const maxval, + int const forceplain) { + + bool const plainFormat = forceplain || pm_plain_output; + + if (maxval > PPM_OVERALLMAXVAL && !plainFormat) + pm_error("too-large maxval passed to ppm_writeppminit(): %d." + "Maximum allowed by the PPM format is %d.", + maxval, PPM_OVERALLMAXVAL); + + fprintf(fileP, "%c%c\n%d %d\n%d\n", + PPM_MAGIC1, + plainFormat || maxval >= 1<<16 ? PPM_MAGIC2 : RPPM_MAGIC2, + cols, rows, maxval ); +#ifdef VMS + if (!plainFormat) + set_outfile_binary(); +#endif +} + + + +static void +putus(unsigned short const n, + FILE * const fileP) { + + if (n >= 10) + putus(n / 10, fileP); + putc('0' + n % 10, fileP); +} + + + +static void +format1bpsRow(const pixel * const pixelrow, + unsigned int const cols, + unsigned char * const rowBuffer) { + + /* single byte samples. */ + + unsigned int col; + unsigned int bufferCursor; + + bufferCursor = 0; + + for (col = 0; col < cols; ++col) { + rowBuffer[bufferCursor++] = PPM_GETR(pixelrow[col]); + rowBuffer[bufferCursor++] = PPM_GETG(pixelrow[col]); + rowBuffer[bufferCursor++] = PPM_GETB(pixelrow[col]); + } +} + + + + +static void +format2bpsRow(const pixel * const pixelrow, + unsigned int const cols, + unsigned char * const rowBuffer) { + + /* two byte samples. */ + + unsigned int col; + unsigned int bufferCursor; + + bufferCursor = 0; + + for (col = 0; col < cols; ++col) { + pixval const r = PPM_GETR(pixelrow[col]); + pixval const g = PPM_GETG(pixelrow[col]); + pixval const b = PPM_GETB(pixelrow[col]); + + rowBuffer[bufferCursor++] = r >> 8; + rowBuffer[bufferCursor++] = (unsigned char)r; + rowBuffer[bufferCursor++] = g >> 8; + rowBuffer[bufferCursor++] = (unsigned char)g; + rowBuffer[bufferCursor++] = b >> 8; + rowBuffer[bufferCursor++] = (unsigned char)b; + } +} + + + +static void +ppm_writeppmrowraw(FILE * const fileP, + const pixel * const pixelrow, + unsigned int const cols, + pixval const maxval ) { + + unsigned int const bytesPerSample = maxval < 256 ? 1 : 2; + unsigned int const bytesPerRow = cols * 3 * bytesPerSample; + + unsigned char * rowBuffer; + ssize_t rc; + + MALLOCARRAY(rowBuffer, bytesPerRow); + + if (rowBuffer == NULL) + pm_error("Unable to allocate memory for row buffer " + "for %u columns", cols); + + if (maxval < 256) + format1bpsRow(pixelrow, cols, rowBuffer); + else + format2bpsRow(pixelrow, cols, rowBuffer); + + rc = fwrite(rowBuffer, 1, bytesPerRow, fileP); + + if (rc < 0) + pm_error("Error writing row. fwrite() errno=%d (%s)", + errno, strerror(errno)); + else if (rc != bytesPerRow) + pm_error("Error writing row. Short write of %u bytes " + "instead of %u", rc, bytesPerRow); + + free(rowBuffer); +} + + + + +static void +ppm_writeppmrowplain(FILE * const fileP, + pixel * const pixelrow, + unsigned int const cols, + pixval const maxval) { + + unsigned int col; + unsigned int charcount; + + charcount = 0; + + for (col = 0; col < cols; ++col) { + if (charcount >= 65) { + putc('\n', fileP); + charcount = 0; + } else if (charcount > 0) { + putc(' ', fileP); + putc(' ', fileP); + charcount += 2; + } + putus(PPM_GETR(pixelrow[col]), fileP); + putc(' ', fileP); + putus(PPM_GETG(pixelrow[col]), fileP); + putc(' ', fileP); + putus(PPM_GETB(pixelrow[col]), fileP); + charcount += 11; + } + if (charcount > 0) + putc('\n', fileP); +} + + + +void +ppm_writeppmrow(FILE * const fileP, + pixel * const pixelrow, + int const cols, + pixval const maxval, + int const forceplain) { + + if (forceplain || pm_plain_output || maxval >= 1<<16) + ppm_writeppmrowplain(fileP, pixelrow, cols, maxval); + else + ppm_writeppmrowraw(fileP, pixelrow, cols, maxval); +} + + + +void +ppm_writeppm(FILE * const file, + pixel** const pixels, + int const cols, + int const rows, + pixval const maxval, + int const forceplain) { + int row; + + ppm_writeppminit(file, cols, rows, maxval, forceplain); + + for (row = 0; row < rows; ++row) + ppm_writeppmrow(file, pixels[row], cols, maxval, forceplain); +} -- cgit 1.4.1