home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Resource Library: Graphics
/
graphics-16000.iso
/
general
/
convrtrs
/
pbmplus
/
ntpbmsrc.lha
/
netpbm
/
ppm
/
ppmtomitsu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-07
|
18KB
|
582 lines
/* ppmtomitsu.c - read a portable pixmap and produce output for the
** Mitsubishi S340-10 Thermo-Sublimation Printer
** (or the S3410-30 parallel interface)
**
** Copyright (C) 1992,93 by S.Petra Zeidler
** Minor modifications by Ingo Wilken:
** - mymalloc() and check_and_rotate() functions for often used
** code fragments. Reduces code size by a few KB.
** - use pm_error() instead of fprintf(stderr)
** - localized allocation of colorhastable
**
** This software was written for the Max Planck Institut fuer Radioastronomie,
** Bonn, Germany, Optical Interferometry group
**
** 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.
*/
static char SCCSid[] = "@(#)ppmtomitsu.c\t\t1.8\t(SPZ)\t3/31/93\n";
#include "ppm.h"
#include "ppmcmap.h"
#include "pbmplus.h"
#include "mitsu.h"
#ifdef __STDC__
int main(int argc, char *argv[] )
#else
int main( argc, argv )
int argc;
char* argv[];
#endif
{
FILE *ifp;
/*hashinfo colorhashtable[HASHSIZE];*/
struct hashinfo *hashrun;
pixel *xP;
int argn;
int dpi300=FALSE;
int cols, rows, format, col, row;
int sharpness, enlarge, copy, tiny;
pixval maxval;
struct mediasize medias;
char media[16];
char *usage = "[-sharpness <1-4>] [-enlarge <1-3>] [-media <a,a4,as,a4s>] [-copy <1-9>] [-tiny] [-dpi300] [ppmfile]";
ppm_init(&argc, argv);
argn = 1;
sharpness = 32;
enlarge = 1;
copy = 1;
memset(media, '\0', 16);
tiny = FALSE;
/* check for flags */
while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
if (pm_keymatch(argv[argn], "-sharpness", 2)) {
++argn;
if (argn == argc || sscanf(argv[argn], "%d", &sharpness) != 1)
pm_usage(usage);
else if (sharpness < 1 || sharpness > 4)
pm_usage(usage);
}
else if (pm_keymatch(argv[argn], "-enlarge", 2)) {
++argn;
if (argn == argc || sscanf(argv[argn], "%d", &enlarge) != 1)
pm_usage(usage);
else if (enlarge < 1 || enlarge > 3)
pm_usage(usage);
}
else if (pm_keymatch(argv[argn], "-media", 2)) {
++argn;
if (argn == argc || sscanf(argv[argn], "%15s", media) < 1)
pm_usage(usage);
else if (mytoupper(media[0]) != 'A')
pm_usage(usage);
}
else if (pm_keymatch(argv[argn], "-copy", 2)) {
++argn;
if (argn == argc || sscanf(argv[argn], "%d", ©) != 1)
pm_usage(usage);
else if (copy < 1 || copy > 9)
pm_usage(usage);
}
else if (pm_keymatch(argv[argn], "-dpi300", 2))
dpi300 = TRUE;
else if (pm_keymatch(argv[argn], "-tiny", 2))
tiny = TRUE;
else
pm_usage(usage);
++argn;
}
if (argn < argc) {
ifp = pm_openr(argv[argn]);
++argn;
}
else
ifp = stdin;
if (argn != argc)
pm_usage(usage);
if (mytoupper(media[0]) == 'A')
switch (mytoupper(media[1])) {
case 'S':
medias = MSize_AS;
break;
case '4':
if(mytoupper(media[2]) == 'S')
medias = MSize_A4S;
else {
medias = MSize_A4;
}
break;
default:
medias = MSize_A;
}
else
medias = MSize_User;
if (dpi300) {
medias.maxcols *= 2;
medias.maxrows *= 2;
}
if (tiny) {
pixel *pixelrow;
char *redrow, *greenrow, *bluerow;
ppm_readppminit(ifp, &cols, &rows, &maxval, &format);
pixelrow = (pixel *) ppm_allocrow(cols);
redrow = mymalloc(cols * sizeof(char));
greenrow = mymalloc(cols * sizeof(char));
bluerow = mymalloc(cols * sizeof(char));
lineputinit(cols, rows, sharpness, enlarge, copy, medias);
for ( row = 0; row < rows; ++row ) {
ppm_readppmrow(ifp, pixelrow, cols, maxval, format);
switch(PPM_FORMAT_TYPE(format)) {
/* color */
case PPM_TYPE:
for (col = 0, xP = pixelrow; col < cols; col++, xP++) {
/* First red. */
redrow[col] = PPM_GETR(*xP);
/* Then green. */
greenrow[col] = PPM_GETG(*xP);
/* And blue. */
bluerow[col] = PPM_GETB(*xP);
}
data(redrow, cols);
data(greenrow, cols);
data(bluerow, cols);
break;
/* grayscale */
default:
for (col = 0, xP = pixelrow; col < cols; col++, xP++)
bluerow[col] = PPM_GETB(*xP);
data(bluerow, cols);
data(bluerow, cols);
data(bluerow, cols);
break;
}
}
pm_close(ifp);
}
else {
pixel **pixelpic;
int colanz, colval;
int i;
colorhist_vector table;
ppm_readppminit( ifp, &cols, &rows, &maxval, &format );
pixelpic = ppm_allocarray( cols, rows );
for (row = 0; row < rows; row++)
ppm_readppmrow( ifp, pixelpic[row], cols, maxval, format );
pm_close(ifp);
/* first check wether we can use the lut transfer */
table = ppm_computecolorhist(pixelpic, cols, rows, MAXLUTCOL+1, &colanz);
if (table != NULL) {
hashinfo *colorhashtable = (hashinfo *)mymalloc(HASHSIZE * sizeof(hashinfo));
for (i=0; i<HASHSIZE; i++) {
colorhashtable[i].flag = -1;
colorhashtable[i].next = NULL;
}
/* we can use the lookuptable */
pm_message("found %d colors - using the lookuptable-method",colanz);
lookuptableinit(sharpness, enlarge, copy, medias);
switch(PPM_FORMAT_TYPE(format)) {
/* color */
case PPM_TYPE:
for (colval=0; colval<colanz; colval++) {
cmd('$');
datum(colval);
datum(PPM_GETR((table[colval]).color));
datum(PPM_GETG((table[colval]).color));
datum(PPM_GETB((table[colval]).color));
hashrun = &colorhashtable[myhash((table[colval]).color)];
if (hashrun->flag == -1) {
hashrun->color = (table[colval]).color;
hashrun->flag = colval;
}
else {
while (hashrun->next != NULL)
hashrun = hashrun->next;
hashrun->next =
(struct hashinfo *) mymalloc(sizeof(struct hashinfo));
hashrun = hashrun->next;
hashrun->color = (table[colval]).color;
hashrun->flag = colval;
hashrun->next = NULL;
}
}
break;
/* other */
default:
for (colval=0; colval<colanz; colval++) {
cmd('$');
datum(colval);
datum(PPM_GETB((table[colval]).color));
datum(PPM_GETB((table[colval]).color));
datum(PPM_GETB((table[colval]).color));
hashrun = &colorhashtable[myhash((table[colval]).color)];
if (hashrun->flag == -1) {
hashrun->color = (table[colval]).color;
hashrun->flag = colval;
}
else {
while (hashrun->next != NULL)
hashrun = hashrun->next;
hashrun->next =
(struct hashinfo *) mymalloc(sizeof(struct hashinfo));
hashrun = hashrun->next;
hashrun->color = (table[colval]).color;
hashrun->flag = colval;
hashrun->next = NULL;
}
}
}
lookuptabledata(cols, rows, enlarge, medias);
for (row=0; row<rows; row++) {
xP = pixelpic[row];
for (col=0; col<cols; col++, xP++) {
hashrun = &colorhashtable[myhash(*xP)];
while (!PPM_EQUAL((hashrun->color), *xP))
if (hashrun->next != NULL)
hashrun = hashrun->next;
else {
pm_error("you just found a lethal bug.");
}
datum(hashrun->flag);
}
}
free(colorhashtable);
}
else {
/* $#%@^!& no lut possible, so send the pic as 24bit */
pm_message("found too many colors for fast lookuptable mode");
frametransferinit(cols, rows, sharpness, enlarge, copy, medias);
switch(PPM_FORMAT_TYPE(format)) {
/* color */
case PPM_TYPE:
COLORDES(RED);
DATASTART; /* red coming */
for (row=0; row<rows; row++) {
xP = pixelpic[row];
for (col=0; col<cols; col++, xP++)
datum(PPM_GETR(*xP));
}
COLORDES(GREEN);
DATASTART; /* green coming */
for (row=0; row<rows; row++) {
xP = pixelpic[row];
for (col=0; col<cols; col++, xP++)
datum(PPM_GETG(*xP));
}
COLORDES(BLUE);
DATASTART; /* blue coming */
for (row=0; row<rows; row++) {
xP = pixelpic[row];
for (col=0; col<cols; col++, xP++)
datum(PPM_GETB(*xP));
}
break;
/* grayscale */
default:
COLORDES(RED);
DATASTART; /* red coming */
for (row=0; row<rows; row++) {
xP = pixelpic[row];
for (col=0; col<cols; col++, xP++)
datum(PPM_GETB(*xP));
}
COLORDES(GREEN);
DATASTART; /* green coming */
for (row=0; row<rows; row++) {
xP = pixelpic[row];
for (col=0; col<cols; col++, xP++)
datum(PPM_GETB(*xP));
}
COLORDES(BLUE);
DATASTART; /* blue coming */
for (row=0; row<rows; row++) {
xP = pixelpic[row];
for (col=0; col<cols; col++, xP++)
datum(PPM_GETB(*xP));
}
}
}
}
PRINTIT;
exit(0);
}
#ifdef __STDC__
static void lineputinit(int cols, int rows,
int sharpness, int enlarge, int copy,
struct mediasize medias)
#else /*__STDC__*/
static int lineputinit(cols, rows, sharpness, enlarge, copy, medias)
int cols, rows;
int sharpness, enlarge, copy;
struct mediasize medias;
#endif /*__STDC__*/
{
ONLINE;
CLRMEM;
MEDIASIZE(medias);
switch (enlarge) {
case 2:
HENLARGE(ENLARGEx2); /* enlarge horizontal */
VENLARGE(ENLARGEx2); /* enlarge vertical */
break;
case 3:
HENLARGE(ENLARGEx3); /* enlarge horizontal */
VENLARGE(ENLARGEx3); /* enlarge vertical */
break;
default:
HENLARGE(NOENLARGE); /* enlarge horizontal */
VENLARGE(NOENLARGE); /* enlarge vertical */
}
COLREVERSION(DONTREVERTCOLOR);
NUMCOPY(copy);
HOFFINCH('\000');
VOFFINCH('\000');
CENTERING(DONTCENTER);
TRANSFERFORMAT(LINEORDER);
COLORSYSTEM(RGB);
GRAYSCALELVL(BIT_8);
switch (sharpness) { /* sharpness :-) */
case 0:
SHARPNESS(SP_NONE);
break;
case 1:
SHARPNESS(SP_LOW);
break;
case 2:
SHARPNESS(SP_MIDLOW);
break;
case 3:
SHARPNESS(SP_MIDHIGH);
break;
case 4:
SHARPNESS(SP_HIGH);
break;
default:
SHARPNESS(SP_USER);
}
check_and_rotate(cols, rows, enlarge, medias);
DATASTART;
return;
}
#ifdef __STDC__
static void lookuptableinit(int sharpness, int enlarge, int copy,
struct mediasize medias)
#else /*__STDC__*/
static int lookuptableinit(sharpness, enlarge, copy, medias)
int sharpness, enlarge, copy;
struct mediasize medias;
#endif /*__STDC__*/
{
ONLINE;
CLRMEM;
MEDIASIZE(medias);
switch (enlarge) {
case 2:
HENLARGE(ENLARGEx2); /* enlarge horizontal */
VENLARGE(ENLARGEx2); /* enlarge vertical */
break;
case 3:
HENLARGE(ENLARGEx3); /* enlarge horizontal */
VENLARGE(ENLARGEx3); /* enlarge vertical */
break;
default:
HENLARGE(NOENLARGE); /* enlarge horizontal */
VENLARGE(NOENLARGE); /* enlarge vertical */
}
COLREVERSION(DONTREVERTCOLOR);
NUMCOPY(copy);
HOFFINCH('\000');
VOFFINCH('\000');
CENTERING(DONTCENTER);
TRANSFERFORMAT(LOOKUPTABLE);
switch (sharpness) { /* sharpness :-) */
case 0:
SHARPNESS(SP_NONE);
break;
case 1:
SHARPNESS(SP_LOW);
break;
case 2:
SHARPNESS(SP_MIDLOW);
break;
case 3:
SHARPNESS(SP_MIDHIGH);
break;
case 4:
SHARPNESS(SP_HIGH);
break;
default:
SHARPNESS(SP_USER);
}
LOADLOOKUPTABLE;
return;
}
#ifdef __STDC__
static void lookuptabledata(int cols, int rows, int enlarge,
struct mediasize medias)
#else /*__STDC__*/
static int lookuptabledata(cols, rows, enlarge, medias)
int rows, cols;
int enlarge;
struct mediasize medias;
#endif /*__STDC__*/
{
DONELOOKUPTABLE;
check_and_rotate(cols, rows, enlarge, medias);
DATASTART;
return;
}
#ifdef __STDC__
static void frametransferinit(int cols, int rows, int sharpness,
int enlarge, int copy, struct mediasize medias)
#else
static int frametransferinit(cols, rows, sharpness, enlarge, copy, medias)
int rows, cols;
int sharpness, enlarge, copy;
struct mediasize medias;
#endif
{
ONLINE;
CLRMEM;
MEDIASIZE(medias);
switch (enlarge) {
case 2:
HENLARGE(ENLARGEx2); /* enlarge horizontal */
VENLARGE(ENLARGEx2); /* enlarge vertical */
break;
case 3:
HENLARGE(ENLARGEx3); /* enlarge horizontal */
VENLARGE(ENLARGEx3); /* enlarge vertical */
break;
default:
HENLARGE(NOENLARGE); /* enlarge horizontal */
VENLARGE(NOENLARGE); /* enlarge vertical */
}
COLREVERSION(DONTREVERTCOLOR);
NUMCOPY(copy);
HOFFINCH('\000');
VOFFINCH('\000');
CENTERING(DONTCENTER);
TRANSFERFORMAT(FRAMEORDER);
COLORSYSTEM(RGB);
GRAYSCALELVL(BIT_8);
switch (sharpness) { /* sharpness :-) */
case 0:
SHARPNESS(SP_NONE);
break;
case 1:
SHARPNESS(SP_LOW);
break;
case 2:
SHARPNESS(SP_MIDLOW);
break;
case 3:
SHARPNESS(SP_MIDHIGH);
break;
case 4:
SHARPNESS(SP_HIGH);
break;
default:
SHARPNESS(SP_USER);
}
check_and_rotate(cols, rows, enlarge, medias);
return;
}
#ifdef __STDC__
static void *
mymalloc(long bytes)
#else
static char *
mymalloc(bytes)
long bytes;
#endif
{
void *mem;
mem = malloc(bytes);
if( mem == NULL )
pm_error("out of memory allocating %d bytes", bytes);
return mem;
}
#ifdef __STDC__
static void
check_and_rotate(int cols, int rows, int enlarge, struct mediasize medias)
#else
static int
check_and_rotate(cols, rows, enlarge, medias)
int cols, rows, enlarge;
struct mediasize medias;
#endif
{
if (cols > rows) {
ROTATEIMG(DOROTATE); /* rotate image */
if (enlarge*rows > medias.maxcols || enlarge*cols > medias.maxrows) {
pm_error("Image too large, MaxPixels = %d x %d", medias.maxrows, medias.maxcols);
}
HPIXELS(cols);
VPIXELS(rows);
HPIXELSOFF((medias.maxcols/enlarge - rows)/2);
VPIXELSOFF((medias.maxrows/enlarge - cols)/2);
pm_message("rotating image for output");
}
else {
ROTATEIMG(DONTROTATE);
if (enlarge*rows > medias.maxrows || enlarge*cols > medias.maxcols) {
pm_error("Image too large, MaxPixels = %d x %d", medias.maxrows, medias.maxcols);
}
HPIXELS(cols);
VPIXELS(rows);
HPIXELSOFF((medias.maxcols/enlarge - cols)/2);
VPIXELSOFF((medias.maxrows/enlarge - rows)/2);
}
}