/* sirtopnm.c - read a Solitaire Image Recorder file and write a portable anymap ** ** Copyright (C) 1991 by Marvin Landis. ** ** 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 "mallocvar.h" #include "pnm.h" static void readSirHeader(FILE * const ifP, int * const formatP, unsigned int * const rowsP, unsigned int * const colsP) { short info; pm_readlittleshort(ifP, &info); if (info != 0x3a4f) pm_error( "Input file is not a Solitaire file"); pm_readlittleshort(ifP, &info); pm_readlittleshort(ifP, &info); if (info == 17) *formatP = PGM_TYPE; else if (info == 11) *formatP = PPM_TYPE; else pm_error( "Input is not MGI TYPE 11 or MGI TYPE 17" ); pm_readlittleshort(ifP, &info); *colsP = info; pm_readlittleshort(ifP, &info); *rowsP = info; { unsigned int i; for (i = 1; i < 1531; ++i) pm_readlittleshort(ifP, &info); } } static void convertPgm(FILE * const ifP, FILE * const ofP, unsigned int const rows, unsigned int const cols, xel * const xelrow) { unsigned int row; pm_message("Writing a PGM file"); for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) PNM_ASSIGN1(xelrow[col], fgetc(ifP)); pnm_writepnmrow(ofP, xelrow, cols, 255, PGM_TYPE, 0); } } static void convertPpm(FILE * const ifP, FILE * const ofP, unsigned int const rows, unsigned int const cols, xel * const xelrow) { unsigned int const picsize = cols * rows * 3; unsigned int const planesize = cols * rows; unsigned char * sirarray; /* malloc'ed array */ unsigned int row; if (UINT_MAX/cols/rows < 3) pm_error("Image is too large (%u x %u x %u) for computation", cols, rows, 3); MALLOCARRAY(sirarray, picsize); if (!sirarray) pm_error( "Not enough memory to load %u x %u x %u SIR file", cols, rows, 3); if (fread(sirarray, 1, picsize, ifP) != picsize) pm_error("Error reading SIR file"); pm_message("Writing a PPM file"); for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; col++) PPM_ASSIGN(xelrow[col], sirarray[row*cols+col], sirarray[planesize + (row*cols+col)], sirarray[2*planesize + (row*cols+col)]); pnm_writepnmrow(ofP, xelrow, cols, 255, PPM_TYPE, 0); } free(sirarray); } int main(int argc, const char ** argv) { FILE * ifP; xel * xelrow; unsigned int rows, cols; int format; pm_proginit(&argc, argv); if (argc-1 > 1) pm_error ("Too many arguments. The only possible argument is " "the input file name"); else if (argc-1 >= 1) ifP = pm_openr(argv[1]); else ifP = stdin; readSirHeader(ifP, &format, &rows, &cols); pnm_writepnminit(stdout, cols, rows, 255, format, 0); xelrow = pnm_allocrow(cols); switch (PNM_FORMAT_TYPE(format)) { case PGM_TYPE: convertPgm(ifP, stdout, rows, cols, xelrow); break; case PPM_TYPE: convertPpm(ifP, stdout, rows, cols, xelrow); break; default: assert(false); } pnm_freerow(xelrow); pm_close(ifP); exit(0); }