/* rawtoppm.c - convert raw RGB bytes into a portable pixmap ** ** Copyright (C) 1991 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 "ppm.h" static void dorowskip ARGS(( FILE* ifp, int rowskip )); int main( argc, argv ) int argc; char* argv[]; { FILE* ifp; pixel* pixrow; register pixel* pP; int argn, headerskip, rowskip, rows, cols, row, i; register int col; int order; #define ORD_RGB 1 #define ORD_RBG 2 #define ORD_GRB 3 #define ORD_GBR 4 #define ORD_BRG 5 #define ORD_BGR 6 int interleave; #define INT_PIX 1 #define INT_ROW 2 int val1, val2, val3; gray* grow1; gray* grow2; gray* grow3; register gray* g1P; register gray* g2P; register gray* g3P; const char* const usage = "[-headerskip N] [-rowskip N] [-rgb|-rbg|-grb|-gbr|-brg|-bgr] [-interpixel|-interrow] [rawfile]"; ppm_init( &argc, argv ); argn = 1; headerskip = 0; rowskip = 0; order = ORD_RGB; interleave = INT_PIX; while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) { if ( pm_keymatch( argv[argn], "-headerskip", 2 ) ) { ++argn; if ( argn >= argc ) pm_usage( usage ); headerskip = atoi( argv[argn] ); } else if ( pm_keymatch( argv[argn], "-rowskip", 3 ) ) { ++argn; if ( argn >= argc ) pm_usage( usage ); rowskip = atoi( argv[argn] ); } else if ( pm_keymatch( argv[argn], "-rgb", 3 ) ) order = ORD_RGB; else if ( pm_keymatch( argv[argn], "-rbg", 3 ) ) order = ORD_RBG; else if ( pm_keymatch( argv[argn], "-grb", 3 ) ) order = ORD_GRB; else if ( pm_keymatch( argv[argn], "-gbr", 3 ) ) order = ORD_GBR; else if ( pm_keymatch( argv[argn], "-brg", 3 ) ) order = ORD_BRG; else if ( pm_keymatch( argv[argn], "-bgr", 3 ) ) order = ORD_BGR; else if ( pm_keymatch( argv[argn], "-interpixel", 7 ) ) interleave = INT_PIX; else if ( pm_keymatch( argv[argn], "-interrow", 7 ) ) interleave = INT_ROW; else pm_usage( usage ); ++argn; } if ( argn + 2 > argc ) pm_usage( usage ); cols = atoi( argv[argn++] ); rows = atoi( argv[argn++] ); if ( cols <= 0 || rows <= 0 ) pm_usage( usage ); if ( argn < argc ) { ifp = pm_openr( argv[argn] ); ++argn; } else ifp = stdin; if ( argn != argc ) pm_usage( usage ); ppm_writeppminit( stdout, cols, rows, (pixval) 255, 0 ); pixrow = ppm_allocrow( cols ); if ( interleave == INT_ROW ) { grow1 = pgm_allocrow( cols ); grow2 = pgm_allocrow( cols ); grow3 = pgm_allocrow( cols ); } for ( i = 0; i < headerskip; ++i ) { val1 = getc( ifp ); if ( val1 == EOF ) pm_error( "EOF / read error" ); } for ( row = 0; row < rows; ++row) { switch ( interleave ) { case INT_PIX: for ( col = 0, pP = pixrow; col < cols; ++col, ++pP ) { val1 = getc( ifp ); if ( val1 == EOF ) pm_error( "EOF / read error" ); val2 = getc( ifp ); if ( val2 == EOF ) pm_error( "EOF / read error" ); val3 = getc( ifp ); if ( val3 == EOF ) pm_error( "EOF / read error" ); switch ( order ) { case ORD_RGB: PPM_ASSIGN( *pP, val1, val2, val3 ); break; case ORD_RBG: PPM_ASSIGN( *pP, val1, val3, val2 ); break; case ORD_GRB: PPM_ASSIGN( *pP, val2, val1, val3 ); break; case ORD_GBR: PPM_ASSIGN( *pP, val3, val1, val2 ); break; case ORD_BRG: PPM_ASSIGN( *pP, val2, val3, val1 ); break; case ORD_BGR: PPM_ASSIGN( *pP, val3, val2, val1 ); break; } } dorowskip( ifp, rowskip ); break; case INT_ROW: for ( col = 0, g1P = grow1; col < cols; ++col, ++g1P ) { val1 = getc( ifp ); if ( val1 == EOF ) pm_error( "EOF / read error" ); *g1P = val1; } dorowskip( ifp, rowskip ); for ( col = 0, g2P = grow2; col < cols; ++col, ++g2P ) { val2 = getc( ifp ); if ( val2 == EOF ) pm_error( "EOF / read error" ); *g2P = val2; } dorowskip( ifp, rowskip ); for ( col = 0, g3P = grow3; col < cols; ++col, ++g3P ) { val3 = getc( ifp ); if ( val3 == EOF ) pm_error( "EOF / read error" ); *g3P = val3; } dorowskip( ifp, rowskip ); for ( col = 0, pP = pixrow, g1P = grow1, g2P = grow2, g3P = grow3; col < cols; ++col, ++pP, ++g1P, ++g2P, ++g3P ) { switch ( order ) { case ORD_RGB: PPM_ASSIGN( *pP, *g1P, *g2P, *g3P ); break; case ORD_RBG: PPM_ASSIGN( *pP, *g1P, *g3P, *g2P ); break; case ORD_GRB: PPM_ASSIGN( *pP, *g2P, *g1P, *g3P ); break; case ORD_GBR: PPM_ASSIGN( *pP, *g3P, *g1P, *g2P ); break; case ORD_BRG: PPM_ASSIGN( *pP, *g2P, *g3P, *g1P ); break; case ORD_BGR: PPM_ASSIGN( *pP, *g3P, *g2P, *g1P ); break; } } break; } ppm_writeppmrow( stdout, pixrow, cols, (pixval) 255, 0 ); } pm_close( ifp ); pm_close( stdout ); exit( 0 ); } static void dorowskip( ifp, rowskip ) FILE* ifp; int rowskip; { int i, val; for ( i = 0; i < rowskip; ++i ) { val = getc( ifp ); if ( val == EOF ) pm_error( "EOF / read error" ); } }