/* libpnm2.c - pnm 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 "netpbm/pm_c_util.h"
#include "pnm.h"
#include "ppm.h"
#include "pgm.h"
#include "pbm.h"
void
pnm_writepnminit(FILE * const fileP,
int const cols,
int const rows,
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_writeppminit(fileP, cols, rows, (pixval) maxval, plainFormat);
break;
case PGM_TYPE:
pgm_writepgminit(fileP, cols, rows, (gray) maxval, plainFormat);
break;
case PBM_TYPE:
pbm_writepbminit(fileP, cols, rows, plainFormat);
break;
default:
pm_error("invalid format argument received by pnm_writepnminit(): %d"
"PNM_FORMAT_TYPE(format) must be %d, %d, or %d",
format, PBM_TYPE, PGM_TYPE, PPM_TYPE);
}
}
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
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);
}
void
pnm_writepnmrow(FILE * const fileP,
const 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:
writepgmrow(fileP, xelrow, cols, maxval, format, plainFormat);
break;
case PBM_TYPE:
writepbmrow(fileP, xelrow, cols, plainFormat);
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);
}
}
void
pnm_writepnm(FILE * const fileP,
xel ** const xels,
int const cols,
int const rows,
xelval const maxval,
int const format,
int const forceplain) {
unsigned int row;
pnm_writepnminit(fileP, cols, rows, maxval, format, forceplain);
for (row = 0; row < rows; ++row)
pnm_writepnmrow(fileP, xels[row], cols, maxval, format, forceplain);
}