1 /* zeisstopnm.c - convert a Zeiss confocal image into a portable anymap
2 **
3 ** Copyright (C) 1993 by Oliver Trepte, oliver@fysik4.kth.se
4 **
5 ** Derived from the pbmplus package,
6 ** Copyright (C) 1989 by Jef Poskanzer.
7 **
8 ** Permission to use, copy, modify, and distribute this software and its
9 ** documentation for any purpose and without fee is hereby granted, provided
10 ** that the above copyright notice appear in all copies and that both that
11 ** copyright notice and this permission notice appear in supporting
12 ** documentation.  This software is provided "as is" without express or
13 ** implied warranty.
14 **
15 **
16 ** This conversion utility is based on a mail from Keith Bartels to
17 ** the confocal mail group (confocal@ubvm.cc.buffalo.edu) in June 1993.
18 **
19 ** I'm including here a description of the Zeiss confocal image format. I
20 ** obtained this over the phone on 4-10-1991 form a Zeiss Engineer, and from
21 ** what I hear, it is probably not correct for the new scopes.
22 ** Zeiss puts its header information and the end of the file, so I call it
23 ** a tailer.  This is nice because most conversions programs that work with raw
24 ** image files will read the image simply ignore the tailer.  The file contains:
25 **
26 ** The image data: NxN  1 byte pixels (where N is the number of pixels in a
27 ** scan line) in a standard raw rastering order.
28 **
29 ** The tailer contains:
30 ** 256 bytes: the blue Look-Up-Table (LUT)
31 ** 256 bytes: the red LUT
32 ** 256 bytes: the green LUT
33 ** 8 bytes: empty
34 ** 2 bytes: no. of columns in the image. hi-byte, low-byte
35 ** 2 bytes: no. of rows in the image.
36 ** 2 bytes: x-position of upper left pixel  (0 for 512x512 images)
37 ** 2 bytes: y-position of upper left pixel  (0 for 512x512 images)
38 ** 16 bytes: empty
39 ** 32 bytes: test from upper right corner of image, ASCII.
40 ** 128 bytes: text from the bottom two rows of the screen, ASCII.
41 ** 64 bytes: reserved
42 ** -----------
43 ** 1024 bytes TOTAL
44 **
45 ** So, image files contain NxN + 1024 bytes.
46 **
47 ** Keith Bartels
48 ** keith@VISION.EE.UTEXAS.EDU
49 **
50 */
51 
52 #include "pnm.h"
53 
54 int
main(argc,argv)55 main( argc, argv )
56     int argc;
57     char* argv[];
58     {
59     FILE* ifp;
60     int argn, row, i;
61     register int col;
62     int rows=0, cols=0;
63     int format = 0;
64     xel* xelrow;
65     register xel* xP;
66     char* buf = NULL;
67     unsigned char *lutr, *lutg, *lutb;
68     long nread = 0;
69     unsigned char* byteP;
70     const char* const usage = "[-pgm|-ppm] [Zeissfile]";
71 
72 
73     pnm_init( &argc, argv );
74 
75     argn = 1;
76 
77     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
78 	{
79 	if ( pm_keymatch( argv[argn], "-pgm", 3 ) )
80 	    {
81 	    if ( argn >= argc )
82 		pm_usage( usage );
83 	    format = PGM_TYPE;
84 	    }
85 	else if ( pm_keymatch( argv[argn], "-ppm", 3 ) )
86 	    {
87 	    if ( argn >= argc )
88 		pm_usage( usage );
89 	    format = PPM_TYPE;
90 	    }
91 	else
92 	    pm_usage( usage );
93 	++argn;
94 	}
95 
96     if ( argn < argc )
97 	{
98 	ifp = pm_openr( argv[argn] );
99 	++argn;
100 	}
101     else
102 	ifp = stdin;
103 
104     if ( argn != argc )
105 	pm_usage( usage );
106 
107     /* Read the image to a buffer */
108 
109     buf = pm_read_unknown_size( ifp, &nread );
110 
111     /* Check the format of the file */
112 
113     if (nread <=1024)
114 	pm_error( "Input file not in Zeiss format (too small)" );
115 
116     lutg = (unsigned char *)buf+(nread-1024+512);
117     lutr = (unsigned char *)buf+(nread-1024+256);
118     lutb = (unsigned char *)buf+(nread-1024);
119 
120     cols = ((unsigned char) buf[nread-1024+768+8]) +
121 	(((unsigned char) buf[nread-1024+768+9]) << 8);
122     rows = ((unsigned char) buf[nread-1024+768+10]) +
123 	(((unsigned char) buf[nread-1024+768+11]) << 8);
124 
125     if ( cols <= 0 )
126 	pm_error( "invalid cols: %d", cols );
127     if ( rows <= 0 )
128 	pm_error( "invalid rows: %d", rows );
129 
130     if (cols*rows != nread-1024)
131 	pm_error( "Hmm, %d rows, %d cols, %ld total image size",
132 		 rows, cols, nread-1024);
133 
134     /* Choose pgm or ppm */
135     /* If the LUTs all contain 0,1,2,3,4..255, it is a pgm file */
136 
137     for (i=0; i<256 && format==0; i++)
138 	if (lutr[i] != i || lutg[i] != i || lutb[i] != i)
139 	    format = PPM_TYPE;
140 
141     if (format == 0)
142 	format = PGM_TYPE;
143 
144     pnm_writepnminit( stdout, cols, rows, 255, format, 0 );
145     xelrow = pnm_allocrow( cols );
146     byteP = (unsigned char *) buf;
147 
148     switch ( PNM_FORMAT_TYPE(format) )
149         {
150         case PGM_TYPE:
151         pm_message( "writing PGM file, %d rows %d columns", rows, cols );
152         break;
153 
154         case PPM_TYPE:
155         pm_message( "writing PPM file, %d rows %d columns", rows, cols );
156         break;
157 
158         default:
159         pm_error( "shouldn't happen" );
160         }
161 
162     for ( row = 0; row < rows; ++row )
163     {
164 	switch ( PNM_FORMAT_TYPE(format) )
165 	{
166 	case PGM_TYPE:
167 	    for ( col = 0, xP = xelrow; col < cols; ++col, ++xP, ++byteP )
168 		PNM_ASSIGN1( *xP, *byteP );
169 	    break;
170 
171 	case PPM_TYPE:
172 	    for ( col = 0, xP = xelrow; col < cols; ++col, ++xP, ++byteP )
173 		PPM_ASSIGN( *xP, lutr[*byteP], lutg[*byteP], lutb[*byteP] );
174 	    break;
175 
176         default:
177 	    pm_error( "shouldn't happen" );
178         }
179 
180 	pnm_writepnmrow( stdout, xelrow, cols, 255, format, 0 );
181     }
182 
183     free( buf );
184     pm_close( stdout );
185 
186     exit( 0 );
187 }
188