home *** CD-ROM | disk | FTP | other *** search
- /* 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);
- }
- }
-
-