1 /* hipstopgm.c - read a HIPS file and produce a portable graymap
2 **
3 ** Copyright (C) 1989 by Jef Poskanzer.
4 **
5 ** Permission to use, copy, modify, and distribute this software and its
6 ** documentation for any purpose and without fee is hereby granted, provided
7 ** that the above copyright notice appear in all copies and that both that
8 ** copyright notice and this permission notice appear in supporting
9 ** documentation.  This software is provided "as is" without express or
10 ** implied warranty.
11 */
12 
13 #include <string.h>
14 
15 #include "nstring.h"
16 #include "pgm.h"
17 
18 struct HIPS_Header {
19     char* orig_name;	/* An indication of the originator of this sequence. */
20     char* seq_name;	/* The sequence name. */
21     int num_frame;	/* The number of frames in this sequence. */
22     char* orig_date;	/* The date the sequence was originated. */
23     int rows;		/* The number of rows in each image, the height. */
24     int cols;		/* The number of columns in each image, the width. */
25     int bits_per_pixel;	/* The number of significant bits per pixel. */
26     int bit_packing;	/* Nonzero if the bits were packed such as to
27                            eliminate any unused bits resulting from a
28                            bits_per_pixel value which was not an even
29                            multiple of eight. */
30     int pixel_format;	/* An indication of the format of each pixel. */
31     char* seq_history;	/* A description of the sequence of transformations
32                            leading up to the current image. */
33     char* seq_desc;	/* A free form description of the contents of the
34                        sequence. */
35 };
36 #define HIPS_PFBYTE 0
37 #define HIPS_PFSHORT 1
38 #define HIPS_PFINT 2
39 #define HIPS_PFFLOAT 3
40 #define HIPS_PFCOMPLEX 4
41 
42 
43 
44 static void
read_line(FILE * const fd,char * const buf,int const size)45 read_line(FILE * const fd,
46           char * const buf,
47           int    const size) {
48 
49     if (fgets( buf, size, fd ) == NULL)
50         pm_error("error reading header");
51 }
52 
53 
54 
55 
56 static void
read_hips_header(fd,hP)57 read_hips_header( fd, hP )
58     FILE* fd;
59     struct HIPS_Header* hP;
60 {
61     char buf[5000];
62 
63     /* Read and toss orig_name. */
64     read_line( fd, buf, 5000 );
65 
66     /* Read and toss seq_name. */
67     read_line( fd, buf, 5000 );
68 
69     /* Read num_frame. */
70     read_line( fd, buf, 5000 );
71     hP->num_frame = atoi( buf );
72 
73     /* Read and toss orig_date. */
74     read_line( fd, buf, 5000 );
75 
76     /* Read rows. */
77     read_line( fd, buf, 5000 );
78     hP->rows = atoi( buf );
79 
80     /* Read cols. */
81     read_line( fd, buf, 5000 );
82     hP->cols = atoi( buf );
83 
84     /* Read bits_per_pixel. */
85     read_line( fd, buf, 5000 );
86     hP->bits_per_pixel = atoi( buf );
87 
88     /* Read bit_packing. */
89     read_line( fd, buf, 5000 );
90     hP->bit_packing = atoi( buf );
91 
92     /* Read pixel_format. */
93     read_line( fd, buf, 5000 );
94     hP->pixel_format = atoi( buf );
95 
96     /* Now read and toss lines until we get one with just a period. */
97     do
98 	{
99         read_line( fd, buf, 5000 );
100 	}
101     while ( !streq( buf, ".\n" ) );
102 }
103 
104 
105 
106 int
main(int argc,char * argv[])107 main(int argc, char * argv[]) {
108 
109     FILE* ifp;
110     gray* grayrow;
111     register gray* gP;
112     int argn, row;
113     register int col;
114     int maxval;
115     int rows, cols;
116     struct HIPS_Header h;
117 
118 
119     pgm_init( &argc, argv );
120 
121     argn = 1;
122 
123     if ( argn < argc )
124 	{
125         ifp = pm_openr( argv[argn] );
126         argn++;
127 	}
128     else
129         ifp = stdin;
130 
131     if ( argn != argc )
132         pm_usage( "[hipsfile]" );
133 
134     read_hips_header( ifp, &h );
135 
136     cols = h.cols;
137     rows = h.rows * h.num_frame;
138 
139     switch ( h.pixel_format )
140 	{
141 	case HIPS_PFBYTE:
142         if ( h.bits_per_pixel != 8 )
143             pm_error(
144                 "can't handle unusual bits_per_pixel %d", h.bits_per_pixel );
145         if ( h.bit_packing != 0 )
146             pm_error( "can't handle bit_packing" );
147         maxval = 255;
148         break;
149 
150 	default:
151         pm_error( "unknown pixel format %d", h.pixel_format );
152 	}
153 
154     pgm_writepgminit( stdout, cols, rows, (gray) maxval, 0 );
155     grayrow = pgm_allocrow( cols );
156     for ( row = 0; row < rows; row++)
157 	{
158         for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
159 	    {
160             int ich;
161 
162             switch ( h.pixel_format )
163             {
164             case HIPS_PFBYTE:
165                 ich = getc( ifp );
166                 if ( ich == EOF )
167                     pm_error( "EOF / read error" );
168                 *gP = (gray) ich;
169                 break;
170 
171             default:
172                 pm_error( "can't happen" );
173             }
174 	    }
175         pgm_writepgmrow( stdout, grayrow, cols, (gray) maxval, 0 );
176 	}
177     pm_close( ifp );
178     pm_close( stdout );
179 
180     return 0;
181 }
182