This is ximtoppm.c in view mode; [Download] [Up]
/* ximtoppm.c - read an Xim file and produce 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 "ppm.h" #include "xim.h" static int ReadXim ARGS(( FILE *in_fp, XimImage *xim )); static int ReadXimHeader ARGS(( FILE *in_fp, XimImage *header )); static int ReadXimImage ARGS(( FILE *in_fp, XimImage *xim )); static int ReadImageChannel ARGS(( FILE *infp, byte *buf, unsigned int *bufsize, int encoded )); int main( argc, argv ) int argc; char *argv[]; { FILE *ifp; XimImage xim; pixel *pixelrow, colormap[256]; register pixel *pP; int argn, rows, cols, row, mapped; register int col; pixval maxval; ppm_init( &argc, argv ); argn = 1; if ( argn < argc ) { ifp = pm_openr( argv[argn] ); ++argn; } else ifp = stdin; if ( argn != argc ) pm_usage( "[ximfile]" ); if ( ! ReadXim( ifp, &xim ) ) pm_error( "can't read Xim file" ); rows = xim.height; cols = xim.width; if ( xim.nchannels == 1 && xim.bits_channel == 8 ) { int i; mapped = 1; maxval = 255; for ( i = 0; i < xim.ncolors; ++i ) { PPM_ASSIGN( colormap[i], xim.colors[i].red, xim.colors[i].grn, xim.colors[i].blu ); /* Should be colormap[xim.colors[i].pixel], but Xim is broken. */ } } else if ( xim.nchannels == 3 ) { mapped = 0; maxval = pm_bitstomaxval( xim.bits_channel ); } else pm_error( "unknown Xim file type, nchannels == %d, bits_channel == %d", xim.nchannels, xim.bits_channel ); ppm_writeppminit( stdout, cols, rows, maxval, 0 ); pixelrow = ppm_allocrow( cols ); for ( row = 0; row < rows; ++row ) { if ( mapped ) { register byte *xbp; for ( col = 0, pP = pixelrow, xbp = xim.data + row * xim.bytes_per_line; col < cols; ++col, ++pP, ++xbp ) *pP = colormap[*xbp]; } else { register byte *xrbp, *xgbp, *xbbp; for ( col = 0, pP = pixelrow, xrbp = xim.data + row * xim.bytes_per_line, xgbp = xim.grn_data + row * xim.bytes_per_line, xbbp = xim.blu_data + row * xim.bytes_per_line; col < cols; ++col, ++pP, ++xrbp, ++xgbp, ++xbbp ) PPM_ASSIGN( *pP, *xrbp, *xgbp, *xbbp ); } ppm_writeppmrow( stdout, pixelrow, cols, maxval, 0 ); } pm_close( ifp ); pm_close( stdout ); exit( 0 ); } /* The rest is excerpted and slightly modified from the X.V11R4 version ** of xim_io.c. */ /*********************************************************************** * File: xlib.c * Author: Philip Thompson * $Date: 89/11/01 10:14:23 $ * $Revision: 1.14 $ * Purpose: General xim libray of utililities * Copyright (c) 1988 Philip R. Thompson * Computer Resource Laboratory (CRL) * Dept. of Architecture and Planning * M.I.T., Rm 9-526 * Cambridge, MA 02139 * This software and its documentation may be used, copied, modified, * and distributed for any purpose without fee, provided: * -- The above copyright notice appears in all copies. * -- This disclaimer appears in all source code copies. * -- The names of M.I.T. and the CRL are not used in advertising * or publicity pertaining to distribution of the software * without prior specific written permission from me or CRL. * I provide this software freely as a public service. It is NOT a * commercial product, and therefore is not subject to an an implied * warranty of merchantability or fitness for a particular purpose. I * provide it as is, without warranty. * This software is furnished only on the basis that any party who * receives it indemnifies and holds harmless the parties who furnish * it against any claims, demands, or liabilities connected with using * it, furnishing it to others, or providing it to a third party. * * Philip R. Thompson (phils@athena.mit.edu) ***********************************************************************/ static int ReadXim(in_fp, xim) FILE *in_fp; XimImage *xim; { if (!ReadXimHeader(in_fp, xim)) { pm_message("can't read xim header" ); return(0); } if (!ReadXimImage(in_fp, xim)) { pm_message("can't read xim data" ); return(0); } return(1); } static int ReadXimHeader(in_fp, header) FILE *in_fp; XimImage *header; { int i; char *cp; XimAsciiHeader a_head; cp = (char *) header; for (i = 0; i < sizeof(XimImage); ++i ) *cp++ = 0; /* Read header and verify image file formats */ if (fread((char *)&a_head, sizeof(ImageHeader), 1, in_fp) != 1) { pm_message("ReadXimHeader: unable to read file header" ); return(0); } if (atoi(a_head.header_size) != sizeof(ImageHeader)) { pm_message("ReadXimHeader: header size mismatch" ); return(0); } if (atoi(a_head.file_version) != IMAGE_VERSION) { pm_message("ReadXimHeader: incorrect Image_file version" ); return(0); } header->width = atoi(a_head.image_width); header->height = atoi(a_head.image_height); header->ncolors = atoi(a_head.num_colors); header->nchannels = atoi(a_head.num_channels); header->bytes_per_line = atoi(a_head.bytes_per_line); /* header->npics = atoi(a_head.num_pictures); */ header->bits_channel = atoi(a_head.bits_per_channel); header->alpha_flag = atoi(a_head.alpha_channel); if (strlen(a_head.author)) { if (!(header->author = calloc((unsigned int)strlen(a_head.author)+1, 1))) { pm_message("ReadXimHeader: can't calloc author string" ); return(0); } header->width = atoi(a_head.image_width); strncpy(header->author, a_head.author, strlen(a_head.author)); } if (strlen(a_head.date)) { if (!(header->date =calloc((unsigned int)strlen(a_head.date)+1,1))){ pm_message("ReadXimHeader: can't calloc date string" ); return(0); } header->width = atoi(a_head.image_width); strncpy(header->date, a_head.date, strlen(a_head.date)); } if (strlen(a_head.program)) { if (!(header->program = calloc( (unsigned int)strlen(a_head.program) + 1, 1))) { pm_message("ReadXimHeader: can't calloc program string" ); return(0); } header->width = atoi(a_head.image_width); strncpy(header->program, a_head.program,strlen(a_head.program)); } /* Do double checking for bakwards compatibility */ if (header->npics == 0) header->npics = 1; if (header->bits_channel == 0) header->bits_channel = 8; else if (header->bits_channel == 24) { header->nchannels = 3; header->bits_channel = 8; } if ((int)header->bytes_per_line == 0) if (header->bits_channel == 1 && header->nchannels == 1) header->bytes_per_line = (header->width + 7) / 8; else header->bytes_per_line = header->width; header->datasize =(unsigned int)header->bytes_per_line * header->height; if (header->nchannels == 3 && header->bits_channel == 8) header->ncolors = 0; else if (header->nchannels == 1 && header->bits_channel == 8) { header->colors = (Color *)calloc((unsigned int)header->ncolors, sizeof(Color)); if (header->colors == NULL) { pm_message("ReadXimHeader: can't calloc colors" ); return(0); } for (i=0; i < header->ncolors; i++) { header->colors[i].red = a_head.c_map[i][0]; header->colors[i].grn = a_head.c_map[i][1]; header->colors[i].blu = a_head.c_map[i][2]; } } return(1); } static int ReadXimImage(in_fp, xim) FILE *in_fp; XimImage *xim; { if (xim->data) { free((char *)xim->data); xim->data = (byte *)0; } if (xim->grn_data) { free((char *)xim->grn_data); xim->grn_data = (byte *)0; } if (xim->blu_data) { free((char *)xim->blu_data); xim->blu_data = (byte *)0; } if (xim->other) { free((char *)xim->other); xim->other = (byte *)0; } xim->npics = 0; if (!(xim->data = (byte *)calloc(xim->datasize, 1))) { pm_message("ReadXimImage: can't malloc pixmap data" ); return(0); } if (!ReadImageChannel(in_fp, xim->data, &xim->datasize, 0)) { pm_message("ReadXimImage: end of the images" ); return(0); } if (xim->nchannels == 3) { xim->grn_data = (byte *)malloc(xim->datasize); xim->blu_data = (byte *)malloc(xim->datasize); if (xim->grn_data == NULL || xim->blu_data == NULL) { pm_message("ReadXimImage: can't malloc rgb channel data" ); free((char *)xim->data); if (xim->grn_data) free((char *)xim->grn_data); if (xim->blu_data) free((char *)xim->blu_data); xim->data = xim->grn_data = xim->blu_data = (byte*)0; return(0); } if (!ReadImageChannel(in_fp, xim->grn_data, &xim->datasize, 0)) return(0); if (!ReadImageChannel(in_fp, xim->blu_data, &xim->datasize, 0)) return(0); } if (xim->alpha_flag) { if ((xim->other = (byte *)malloc(xim->datasize)) == NULL) { pm_message("ReadXimImage: can't malloc alpha data" ); return(0); } if (!ReadImageChannel(in_fp, xim->other, &xim->datasize, 0)) return(0); } xim->npics = 1; return(1); } static int ReadImageChannel(infp, buf, bufsize, encoded) FILE *infp; byte *buf; unsigned int *bufsize; int encoded; { register int i, runlen, nbytes; register unsigned int j; register byte *line; long marker; if (!encoded) j = fread((char *)buf, 1, (int)*bufsize, infp); else { if ((line=(byte *)malloc((unsigned int)BUFSIZ)) == NULL) { pm_message("ReadImageChannel: can't malloc() fread string" ); return(0); } /* Unrunlength encode data */ marker = ftell(infp); j = 0; while (((nbytes=fread((char *)line, 1, BUFSIZ, infp)) > 0) && (j < *bufsize)) { for (i=0; (i < nbytes) && (j < *bufsize); i++) { runlen = (int)line[i]+1; i++; while (runlen--) buf[j++] = line[i]; } marker += i; } /* return to the begining of the next image's bufffer */ if (fseek(infp, marker, 0) == -1) { pm_message("ReadImageChannel: can't fseek to location in image buffer" ); return(0); } free((char *)line); } if (j != *bufsize) { pm_message("unable to complete channel: %u / %u (%d%%)", j, *bufsize, (int)(j*100.0 / *bufsize) ); *bufsize = j; } return(1); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.