ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/freemol/trunk/src/mpeg_encode/src/libpnmrw.c
Revision: 22
Committed: Mon Jul 7 22:16:37 2008 UTC (11 years, 3 months ago) by wdelano
File size: 37343 byte(s)
Log Message:
initial checkin of mpeg_encode source
Line File contents
1 /* libpnmrw.c - PBM/PGM/PPM read/write library
2 **
3 ** Copyright (C) 1988, 1989, 1991, 1992 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 #define pm_error(x) exit(1)
14
15
16 #if defined(SVR2) || defined(SVR3) || defined(SVR4)
17 #define SYSV
18 #endif
19 #if ! ( defined(BSD) || defined(SYSV) || defined(MSDOS) )
20 /* CONFIGURE: If your system is >= 4.2BSD, set the BSD option; if you're a
21 ** System V site, set the SYSV option; and if you're IBM-compatible, set
22 ** MSDOS. If your compiler is ANSI C, you're probably better off setting
23 ** SYSV - all it affects is string handling.
24 */
25 #define BSD
26 /* #define SYSV */
27 /* #define MSDOS */
28 #endif
29
30 #include <stdio.h>
31 #include "libpnmrw.h"
32
33 /* if don't have string.h, try strings.h */
34 #include <string.h>
35 #define rindex(s,c) strrchr(s,c)
36
37
38 /* Definitions. */
39
40 #define pbm_allocarray( cols, rows ) ((bit**) pm_allocarray( cols, rows, sizeof(bit) ))
41 #define pbm_allocrow( cols ) ((bit*) pm_allocrow( cols, sizeof(bit) ))
42 #define pbm_freearray( bits, rows ) pm_freearray( (char**) bits, rows )
43 #define pbm_freerow( bitrow ) pm_freerow( (char*) bitrow )
44 #define pgm_allocarray( cols, rows ) ((gray**) pm_allocarray( cols, rows, sizeof(gray) ))
45 #define pgm_allocrow( cols ) ((gray*) pm_allocrow( cols, sizeof(gray) ))
46 #define pgm_freearray( grays, rows ) pm_freearray( (char**) grays, rows )
47 #define pgm_freerow( grayrow ) pm_freerow( (char*) grayrow )
48 #define ppm_allocarray( cols, rows ) ((pixel**) pm_allocarray( cols, rows, sizeof(pixel) ))
49 #define ppm_allocrow( cols ) ((pixel*) pm_allocrow( cols, sizeof(pixel) ))
50 #define ppm_freearray( pixels, rows ) pm_freearray( (char**) pixels, rows )
51 #define ppm_freerow( pixelrow ) pm_freerow( (char*) pixelrow )
52
53
54 /* Variables. */
55
56 static char* progname;
57
58
59 /* Variable-sized arrays. */
60
61 char*
62 pm_allocrow( cols, size )
63 int cols;
64 int size;
65 {
66 register char* itrow;
67
68 itrow = (char*) malloc( cols * size );
69 if ( itrow == (char*) 0 )
70 {
71 (void) fprintf(
72 stderr, "%s: out of memory allocating a row\n", progname );
73 return (char*) 0;
74 }
75 return itrow;
76 }
77
78 void
79 pm_freerow( itrow )
80 char* itrow;
81 {
82 free( itrow );
83 }
84
85 char**
86 pm_allocarray( cols, rows, size )
87 int cols, rows;
88 int size;
89 {
90 char** its;
91 int i;
92
93 its = (char**) malloc( rows * sizeof(char*) );
94 if ( its == (char**) 0 )
95 {
96 (void) fprintf(
97 stderr, "%s: out of memory allocating an array\n", progname );
98 return (char**) 0;
99 }
100 its[0] = (char*) malloc( rows * cols * size );
101 if ( its[0] == (char*) 0 )
102 {
103 (void) fprintf(
104 stderr, "%s: out of memory allocating an array\n", progname );
105 free( (char*) its );
106 return (char**) 0;
107 }
108 for ( i = 1; i < rows; ++i )
109 its[i] = &(its[0][i * cols * size]);
110 return its;
111 }
112
113 void
114 pm_freearray( its, rows )
115 char** its;
116 int rows;
117 {
118 free( its[0] );
119 free( its );
120 }
121
122
123 /* File open/close that handles "-" as stdin and checks errors. */
124
125 static void
126 pm_perror( reason )
127 char* reason;
128 {
129 /*
130 extern char* sys_errlist[];
131 extern int errno;
132 char* e;
133
134 e = sys_errlist[errno];
135
136 if ( reason != 0 && reason[0] != '\0' )
137 (void) fprintf( stderr, "%s: %s - %s\n", progname, reason, e );
138 else
139 (void) fprintf( stderr, "%s: %s\n", progname, e );
140 */
141
142 }
143
144 FILE*
145 pm_openr( name )
146 char* name;
147 {
148 FILE* f;
149
150 if ( strcmp( name, "-" ) == 0 )
151 f = stdin;
152 else
153 {
154 f = fopen( name, "rb" );
155 if ( f == NULL )
156 {
157 pm_perror( name );
158 return (FILE*) 0;
159 }
160 }
161 return f;
162 }
163
164 FILE*
165 pm_openw( name )
166 char* name;
167 {
168 FILE* f;
169
170 f = fopen( name, "wb" );
171 if ( f == NULL ) {
172 pm_perror( name );
173 return (FILE*) 0;
174 }
175 return f;
176 }
177
178 int
179 pm_closer( f )
180 FILE* f;
181 {
182 if ( ferror( f ) )
183 {
184 (void) fprintf(
185 stderr, "%s: a file read error occurred at some point\n",
186 progname );
187 return -1;
188 }
189 if ( f != stdin )
190 if ( fclose( f ) != 0 )
191 {
192 pm_perror( "fclose" );
193 return -1;
194 }
195 return 0;
196 }
197
198 int
199 pm_closew( f )
200 FILE* f;
201 {
202 fflush( f );
203 if ( ferror( f ) )
204 {
205 (void) fprintf(
206 stderr, "%s: a file write error occurred at some point\n",
207 progname );
208 return -1;
209 }
210 if ( f != stdout )
211 if ( fclose( f ) != 0 )
212 {
213 pm_perror( "fclose" );
214 return -1;
215 }
216 return 0;
217 }
218
219 static int
220 pbm_getc( file )
221 FILE* file;
222 {
223 register int ich;
224
225 ich = getc( file );
226 if ( ich == EOF )
227 {
228 (void) fprintf( stderr, "%s: EOF / read error\n", progname );
229 return EOF;
230 }
231
232 if ( ich == '#' )
233 {
234 do
235 {
236 ich = getc( file );
237 if ( ich == EOF )
238 {
239 (void) fprintf( stderr, "%s: EOF / read error\n", progname );
240 return EOF;
241 }
242 }
243 while ( ich != '\n' && ich != '\r' );
244 }
245
246 return ich;
247 }
248
249 static bit
250 pbm_getbit( file )
251 FILE* file;
252 {
253 register int ich;
254
255 do
256 {
257 ich = pbm_getc( file );
258 if ( ich == EOF )
259 return -1;
260 }
261 while ( ich == ' ' || ich == '\t' || ich == '\n' || ich == '\r' );
262
263 if ( ich != '0' && ich != '1' )
264 {
265 (void) fprintf(
266 stderr, "%s: junk in file where bits should be\n", progname );
267 return -1;
268 }
269
270 return ( ich == '1' ) ? 1 : 0;
271 }
272
273 static int
274 pbm_readmagicnumber( file )
275 FILE* file;
276 {
277 int ich1, ich2;
278
279 ich1 = getc( file );
280 if ( ich1 == EOF )
281 {
282 (void) fprintf(
283 stderr, "%s: EOF / read error reading magic number\n", progname );
284 return -1;
285 }
286 ich2 = getc( file );
287 if ( ich2 == EOF )
288 {
289 (void) fprintf(
290 stderr, "%s: EOF / read error reading magic number\n", progname );
291 return -1;
292 }
293 return ich1 * 256 + ich2;
294 }
295
296 static int
297 pbm_getint( file )
298 FILE* file;
299 {
300 register int ich;
301 register int i;
302
303 do
304 {
305 ich = pbm_getc( file );
306 if ( ich == EOF )
307 return -1;
308 }
309 while ( ich == ' ' || ich == '\t' || ich == '\n' || ich == '\r' );
310
311 if ( ich < '0' || ich > '9' )
312 {
313 (void) fprintf(
314 stderr, "%s: junk in file where an integer should be\n", progname );
315 return -1;
316 }
317
318 i = 0;
319 do
320 {
321 i = i * 10 + ich - '0';
322 ich = pbm_getc( file );
323 if ( ich == EOF )
324 return -1;
325 }
326 while ( ich >= '0' && ich <= '9' );
327
328 return i;
329 }
330
331 static int
332 pbm_readpbminitrest( file, colsP, rowsP )
333 FILE* file;
334 int* colsP;
335 int* rowsP;
336 {
337 /* Read size. */
338 *colsP = pbm_getint( file );
339 *rowsP = pbm_getint( file );
340 if ( *colsP == -1 || *rowsP == -1 )
341 return -1;
342 return 0;
343 }
344
345 static int
346 pbm_getrawbyte( file )
347 FILE* file;
348 {
349 register int iby;
350
351 iby = getc( file );
352 if ( iby == EOF )
353 {
354 (void) fprintf( stderr, "%s: EOF / read error\n", progname );
355 return -1;
356 }
357 return iby;
358 }
359
360 static int
361 pbm_readpbmrow( file, bitrow, cols, format )
362 FILE* file;
363 bit* bitrow;
364 int cols, format;
365 {
366 register int col, bitshift, b;
367 register int item;
368 register bit* bP;
369
370 switch ( format )
371 {
372 case PBM_FORMAT:
373 for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
374 {
375 b = pbm_getbit( file );
376 if ( b == -1 )
377 return -1;
378 *bP = b;
379 }
380 break;
381
382 case RPBM_FORMAT:
383 bitshift = -1;
384 for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
385 {
386 if ( bitshift == -1 )
387 {
388 item = pbm_getrawbyte( file );
389 if ( item == -1 )
390 return -1;
391 bitshift = 7;
392 }
393 *bP = ( item >> bitshift ) & 1;
394 --bitshift;
395 }
396 break;
397
398 default:
399 (void) fprintf( stderr, "%s: can't happen\n", progname );
400 return -1;
401 }
402 return 0;
403 }
404
405 static void
406 pbm_writepbminit( file, cols, rows, forceplain )
407 FILE* file;
408 int cols, rows;
409 int forceplain;
410 {
411 if ( ! forceplain )
412 (void) fprintf(
413 file, "%c%c\n%d %d\n", PBM_MAGIC1, RPBM_MAGIC2, cols, rows );
414 else
415 (void) fprintf(
416 file, "%c%c\n%d %d\n", PBM_MAGIC1, PBM_MAGIC2, cols, rows );
417 }
418
419 static void
420 pbm_writepbmrowraw( file, bitrow, cols )
421 FILE* file;
422 bit* bitrow;
423 int cols;
424 {
425 register int col, bitshift;
426 register unsigned char item;
427 register bit* bP;
428
429 bitshift = 7;
430 item = 0;
431 for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
432 {
433 if ( *bP )
434 item += 1 << bitshift;
435 --bitshift;
436 if ( bitshift == -1 )
437 {
438 (void) putc( item, file );
439 bitshift = 7;
440 item = 0;
441 }
442 }
443 if ( bitshift != 7 )
444 (void) putc( item, file );
445 }
446
447 static void
448 pbm_writepbmrowplain( file, bitrow, cols )
449 FILE* file;
450 bit* bitrow;
451 int cols;
452 {
453 register int col, charcount;
454 register bit* bP;
455
456 charcount = 0;
457 for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
458 {
459 if ( charcount >= 70 )
460 {
461 (void) putc( '\n', file );
462 charcount = 0;
463 }
464 putc( *bP ? '1' : '0', file );
465 ++charcount;
466 }
467 (void) putc( '\n', file );
468 }
469
470 static void
471 pbm_writepbmrow( file, bitrow, cols, forceplain )
472 FILE* file;
473 bit* bitrow;
474 int cols;
475 int forceplain;
476 {
477 if ( ! forceplain )
478 pbm_writepbmrowraw( file, bitrow, cols );
479 else
480 pbm_writepbmrowplain( file, bitrow, cols );
481 }
482
483 static int
484 pgm_readpgminitrest( file, colsP, rowsP, maxvalP )
485 FILE* file;
486 int* colsP;
487 int* rowsP;
488 gray* maxvalP;
489 {
490 int maxval;
491
492 /* Read size. */
493 *colsP = pbm_getint( file );
494 *rowsP = pbm_getint( file );
495 if ( *colsP == -1 || *rowsP == -1 )
496 return -1;
497
498 /* Read maxval. */
499 maxval = pbm_getint( file );
500 if ( maxval == -1 )
501 return -1;
502 if ( maxval > PGM_MAXMAXVAL )
503 {
504 (void) fprintf( stderr, "%s: maxval is too large\n", progname );
505 return -1;
506 }
507 *maxvalP = maxval;
508 return 0;
509 }
510
511 #if __STDC__
512 static int
513 pgm_readpgmrow( FILE* file, gray* grayrow, int cols, gray maxval, int format )
514 #else /*__STDC__*/
515 static int
516 pgm_readpgmrow( file, grayrow, cols, maxval, format )
517 FILE* file;
518 gray* grayrow;
519 int cols;
520 gray maxval;
521 int format;
522 #endif /*__STDC__*/
523 {
524 register int col, val;
525 register gray* gP;
526 /*
527 bit* bitrow;
528 register bit* bP;
529 */
530
531 switch ( format )
532 {
533 case PGM_FORMAT:
534 for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
535 {
536 val = pbm_getint( file );
537 if ( val == -1 )
538 return -1;
539 *gP = val;
540 }
541 break;
542
543 case RPGM_FORMAT:
544 if ( fread( grayrow, 1, cols, file ) != cols )
545 {
546 (void) fprintf( stderr, "%s: EOF / read error\n", progname );
547 return -1;
548 }
549 break;
550
551 default:
552 (void) fprintf( stderr, "%s: can't happen\n", progname );
553 return -1;
554 }
555 return 0;
556 }
557
558 #if __STDC__
559 static void
560 pgm_writepgminit( FILE* file, int cols, int rows, gray maxval, int forceplain )
561 #else /*__STDC__*/
562 static void
563 pgm_writepgminit( file, cols, rows, maxval, forceplain )
564 FILE* file;
565 int cols, rows;
566 gray maxval;
567 int forceplain;
568 #endif /*__STDC__*/
569 {
570 if ( maxval <= 255 && ! forceplain )
571 fprintf(
572 file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, RPGM_MAGIC2,
573 cols, rows, maxval );
574 else
575 fprintf(
576 file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, PGM_MAGIC2,
577 cols, rows, maxval );
578 }
579
580 static void
581 putus( n, file )
582 unsigned short n;
583 FILE* file;
584 {
585 if ( n >= 10 )
586 putus( n / 10, file );
587 putc( n % 10 + '0', file );
588 }
589
590 static int
591 pgm_writepgmrowraw( file, grayrow, cols, maxval )
592 FILE* file;
593 gray* grayrow;
594 int cols;
595 gray maxval;
596 {
597 if ( fwrite( grayrow, 1, cols, file ) != cols )
598 {
599 (void) fprintf( stderr, "%s: write error\n", progname );
600 return -1;
601 }
602 return 0;
603 }
604
605 static int
606 pgm_writepgmrowplain( file, grayrow, cols, maxval )
607 FILE* file;
608 gray* grayrow;
609 int cols;
610 gray maxval;
611 {
612 register int col, charcount;
613 register gray* gP;
614
615 charcount = 0;
616 for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
617 {
618 if ( charcount >= 65 )
619 {
620 (void) putc( '\n', file );
621 charcount = 0;
622 }
623 else if ( charcount > 0 )
624 {
625 (void) putc( ' ', file );
626 ++charcount;
627 }
628 putus( (unsigned short) *gP, file );
629 charcount += 3;
630 }
631 if ( charcount > 0 )
632 (void) putc( '\n', file );
633 return 0;
634 }
635
636 #if __STDC__
637 static int
638 pgm_writepgmrow( FILE* file, gray* grayrow, int cols, gray maxval, int forceplain )
639 #else /*__STDC__*/
640 static int
641 pgm_writepgmrow( file, grayrow, cols, maxval, forceplain )
642 FILE* file;
643 gray* grayrow;
644 int cols;
645 gray maxval;
646 int forceplain;
647 #endif /*__STDC__*/
648 {
649 if ( maxval <= 255 && ! forceplain )
650 return pgm_writepgmrowraw( file, grayrow, cols, maxval );
651 else
652 return pgm_writepgmrowplain( file, grayrow, cols, maxval );
653 }
654
655 static int
656 ppm_readppminitrest( file, colsP, rowsP, maxvalP )
657 FILE* file;
658 int* colsP;
659 int* rowsP;
660 pixval* maxvalP;
661 {
662 int maxval;
663
664 /* Read size. */
665 *colsP = pbm_getint( file );
666 *rowsP = pbm_getint( file );
667 if ( *colsP == -1 || *rowsP == -1 )
668 return -1;
669
670 /* Read maxval. */
671 maxval = pbm_getint( file );
672 if ( maxval == -1 )
673 return -1;
674 if ( maxval > PPM_MAXMAXVAL )
675 {
676 (void) fprintf( stderr, "%s: maxval is too large\n", progname );
677 return -1;
678 }
679 *maxvalP = maxval;
680 return 0;
681 }
682
683 #if __STDC__
684 static int
685 ppm_readppmrow( FILE* file, pixel* pixelrow, int cols, pixval maxval, int format )
686 #else /*__STDC__*/
687 static int
688 ppm_readppmrow( file, pixelrow, cols, maxval, format )
689 FILE* file;
690 pixel* pixelrow;
691 int cols, format;
692 pixval maxval;
693 #endif /*__STDC__*/
694 {
695 register int col;
696 register pixel* pP;
697 register int r, g, b;
698 gray* grayrow;
699 register gray* gP;
700 /*
701 bit* bitrow;
702 register bit* bP;
703 */
704
705 switch ( format )
706 {
707 case PPM_FORMAT:
708 for ( col = 0, pP = pixelrow; col < cols; ++col, ++pP )
709 {
710 r = pbm_getint( file );
711 g = pbm_getint( file );
712 b = pbm_getint( file );
713 if ( r == -1 || g == -1 || b == -1 )
714 return -1;
715 PPM_ASSIGN( *pP, r, g, b );
716 }
717 break;
718
719 case RPPM_FORMAT:
720 grayrow = pgm_allocrow( 3 * cols );
721 if ( grayrow == (gray*) 0 )
722 return -1;
723 if ( fread( grayrow, 1, 3 * cols, file ) != 3 * cols )
724 {
725 (void) fprintf( stderr, "%s: EOF / read error\n", progname );
726 return -1;
727 }
728 for ( col = 0, gP = grayrow, pP = pixelrow; col < cols; ++col, ++pP )
729 {
730 r = *gP++;
731 g = *gP++;
732 b = *gP++;
733 PPM_ASSIGN( *pP, r, g, b );
734 }
735 pgm_freerow( grayrow );
736 break;
737
738 default:
739 (void) fprintf( stderr, "%s: can't happen\n", progname );
740 return -1;
741 }
742 return 0;
743 }
744
745 #if __STDC__
746 static void
747 ppm_writeppminit( FILE* file, int cols, int rows, pixval maxval, int forceplain )
748 #else /*__STDC__*/
749 static void
750 ppm_writeppminit( file, cols, rows, maxval, forceplain )
751 FILE* file;
752 int cols, rows;
753 pixval maxval;
754 int forceplain;
755 #endif /*__STDC__*/
756 {
757 if ( maxval <= 255 && ! forceplain )
758 fprintf(
759 file, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, RPPM_MAGIC2,
760 cols, rows, maxval );
761 else
762 fprintf(
763 file, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, PPM_MAGIC2,
764 cols, rows, maxval );
765 }
766
767 static int
768 ppm_writeppmrowraw( file, pixelrow, cols, maxval )
769 FILE* file;
770 pixel* pixelrow;
771 int cols;
772 pixval maxval;
773 {
774 register int col;
775 register pixel* pP;
776 gray* grayrow;
777 register gray* gP;
778
779 grayrow = pgm_allocrow( 3 * cols );
780 if ( grayrow == (gray*) 0 )
781 return -1;
782 for ( col = 0, pP = pixelrow, gP = grayrow; col < cols; ++col, ++pP )
783 {
784 *gP++ = PPM_GETR( *pP );
785 *gP++ = PPM_GETG( *pP );
786 *gP++ = PPM_GETB( *pP );
787 }
788 if ( fwrite( grayrow, 1, 3 * cols, file ) != 3 * cols )
789 {
790 (void) fprintf( stderr, "%s: write error\n", progname );
791 return -1;
792 }
793 pgm_freerow( grayrow );
794 return 0;
795 }
796
797 static int
798 ppm_writeppmrowplain( file, pixelrow, cols, maxval )
799 FILE* file;
800 pixel* pixelrow;
801 int cols;
802 pixval maxval;
803 {
804 register int col, charcount;
805 register pixel* pP;
806 register pixval val;
807
808 charcount = 0;
809 for ( col = 0, pP = pixelrow; col < cols; ++col, ++pP )
810 {
811 if ( charcount >= 65 )
812 {
813 (void) putc( '\n', file );
814 charcount = 0;
815 }
816 else if ( charcount > 0 )
817 {
818 (void) putc( ' ', file );
819 (void) putc( ' ', file );
820 charcount += 2;
821 }
822 val = PPM_GETR( *pP );
823 putus( val, file );
824 (void) putc( ' ', file );
825 val = PPM_GETG( *pP );
826 putus( val, file );
827 (void) putc( ' ', file );
828 val = PPM_GETB( *pP );
829 putus( val, file );
830 charcount += 11;
831 }
832 if ( charcount > 0 )
833 (void) putc( '\n', file );
834 return 0;
835 }
836
837 #if __STDC__
838 static int
839 ppm_writeppmrow( FILE* file, pixel* pixelrow, int cols, pixval maxval, int forceplain )
840 #else /*__STDC__*/
841 static int
842 ppm_writeppmrow( file, pixelrow, cols, maxval, forceplain )
843 FILE* file;
844 pixel* pixelrow;
845 int cols;
846 pixval maxval;
847 int forceplain;
848 #endif /*__STDC__*/
849 {
850 if ( maxval <= 255 && ! forceplain )
851 return ppm_writeppmrowraw( file, pixelrow, cols, maxval );
852 else
853 return ppm_writeppmrowplain( file, pixelrow, cols, maxval );
854 }
855
856 void
857 pnm_init2( pn )
858 char* pn;
859 {
860 /* Save program name. */
861 progname = pn;
862 }
863
864 xelval pnm_pbmmaxval = 1;
865
866 int
867 pnm_readpnminit( file, colsP, rowsP, maxvalP, formatP )
868 FILE* file;
869 int* colsP;
870 int* rowsP;
871 int* formatP;
872 xelval* maxvalP;
873 {
874 gray gmaxval;
875
876 /* Check magic number. */
877 *formatP = pbm_readmagicnumber( file );
878 if ( *formatP == -1 )
879 return -1;
880 switch ( PNM_FORMAT_TYPE(*formatP) )
881 {
882 case PPM_TYPE:
883 if ( ppm_readppminitrest( file, colsP, rowsP, (pixval*) maxvalP ) < 0 )
884 return -1;
885 break;
886
887 case PGM_TYPE:
888 if ( pgm_readpgminitrest( file, colsP, rowsP, &gmaxval ) < 0 )
889 return -1;
890 *maxvalP = (xelval) gmaxval;
891 break;
892
893 case PBM_TYPE:
894 if ( pbm_readpbminitrest( file, colsP, rowsP ) < 0 )
895 return -1;
896 *maxvalP = pnm_pbmmaxval;
897 break;
898
899 default:
900 (void) fprintf(
901 stderr, "%s: bad magic number - not a ppm, pgm, or pbm file\n",
902 progname );
903 return -1;
904 }
905 return 0;
906 }
907
908 #if __STDC__
909 int
910 pnm_readpnmrow( FILE* file, xel* xelrow, int cols, xelval maxval, int format )
911 #else /*__STDC__*/
912 int
913 pnm_readpnmrow( file, xelrow, cols, maxval, format )
914 FILE* file;
915 xel* xelrow;
916 xelval maxval;
917 int cols, format;
918 #endif /*__STDC__*/
919 {
920 register int col;
921 register xel* xP;
922 gray* grayrow;
923 register gray* gP;
924 bit* bitrow;
925 register bit* bP;
926
927 switch ( PNM_FORMAT_TYPE(format) )
928 {
929 case PPM_TYPE:
930 if ( ppm_readppmrow( file, (pixel*) xelrow, cols, (pixval) maxval, format ) < 0 )
931 return -1;
932 break;
933
934 case PGM_TYPE:
935 grayrow = pgm_allocrow( cols );
936 if ( grayrow == (gray*) 0 )
937 return -1;
938 if ( pgm_readpgmrow( file, grayrow, cols, (gray) maxval, format ) < 0 )
939 return -1;
940 for ( col = 0, xP = xelrow, gP = grayrow; col < cols; ++col, ++xP, ++gP )
941 PNM_ASSIGN1( *xP, *gP );
942 pgm_freerow( grayrow );
943 break;
944
945 case PBM_TYPE:
946 bitrow = pbm_allocrow( cols );
947 if ( bitrow == (bit*) 0 )
948 return -1;
949 if ( pbm_readpbmrow( file, bitrow, cols, format ) < 0 )
950 {
951 pbm_freerow( bitrow );
952 return -1;
953 }
954 for ( col = 0, xP = xelrow, bP = bitrow; col < cols; ++col, ++xP, ++bP )
955 PNM_ASSIGN1( *xP, *bP == PBM_BLACK ? 0: pnm_pbmmaxval );
956 pbm_freerow( bitrow );
957 break;
958
959 default:
960 (void) fprintf( stderr, "%s: can't happen\n", progname );
961 return -1;
962 }
963 return 0;
964 }
965
966 xel**
967 pnm_readpnm( file, colsP, rowsP, maxvalP, formatP )
968 FILE* file;
969 int* colsP;
970 int* rowsP;
971 int* formatP;
972 xelval* maxvalP;
973 {
974 xel** xels;
975 int row;
976
977 if ( pnm_readpnminit( file, colsP, rowsP, maxvalP, formatP ) < 0 )
978 return (xel**) 0;
979
980 xels = pnm_allocarray( *colsP, *rowsP );
981 if ( xels == (xel**) 0 )
982 return (xel**) 0;
983
984 for ( row = 0; row < *rowsP; ++row )
985 if ( pnm_readpnmrow( file, xels[row], *colsP, *maxvalP, *formatP ) < 0 )
986 {
987 pnm_freearray( xels, *rowsP );
988 return (xel**) 0;
989 }
990
991 return xels;
992 }
993
994 #if __STDC__
995 int
996 pnm_writepnminit( FILE* file, int cols, int rows, xelval maxval, int format, int forceplain )
997 #else /*__STDC__*/
998 int
999 pnm_writepnminit( file, cols, rows, maxval, format, forceplain )
1000 FILE* file;
1001 int cols, rows, format;
1002 xelval maxval;
1003 int forceplain;
1004 #endif /*__STDC__*/
1005 {
1006 switch ( PNM_FORMAT_TYPE(format) )
1007 {
1008 case PPM_TYPE:
1009 ppm_writeppminit( file, cols, rows, (pixval) maxval, forceplain );
1010 break;
1011
1012 case PGM_TYPE:
1013 pgm_writepgminit( file, cols, rows, (gray) maxval, forceplain );
1014 break;
1015
1016 case PBM_TYPE:
1017 pbm_writepbminit( file, cols, rows, forceplain );
1018 break;
1019
1020 default:
1021 (void) fprintf( stderr, "%s: can't happen\n", progname );
1022 return -1;
1023 }
1024 return 0;
1025 }
1026
1027 #if __STDC__
1028 int
1029 pnm_writepnmrow( FILE* file, xel* xelrow, int cols, xelval maxval, int format, int forceplain )
1030 #else /*__STDC__*/
1031 int
1032 pnm_writepnmrow( file, xelrow, cols, maxval, format, forceplain )
1033 FILE* file;
1034 xel* xelrow;
1035 int cols, format;
1036 xelval maxval;
1037 int forceplain;
1038 #endif /*__STDC__*/
1039 {
1040 register int col;
1041 register xel* xP;
1042 gray* grayrow;
1043 register gray* gP;
1044 bit* bitrow;
1045 register bit* bP;
1046
1047 switch ( PNM_FORMAT_TYPE(format) )
1048 {
1049 case PPM_TYPE:
1050 if ( ppm_writeppmrow( file, (pixel*) xelrow, cols, (pixval) maxval, forceplain ) < 0 )
1051 return -1;
1052 break;
1053
1054 case PGM_TYPE:
1055 grayrow = pgm_allocrow( cols );
1056 if ( grayrow == (gray*) 0 )
1057 return -1;
1058 for ( col = 0, gP = grayrow, xP = xelrow; col < cols; ++col, ++gP, ++xP )
1059 *gP = PNM_GET1( *xP );
1060 if ( pgm_writepgmrow( file, grayrow, cols, (gray) maxval, forceplain ) < 0 )
1061 {
1062 pgm_freerow( grayrow );
1063 return -1;
1064 }
1065 pgm_freerow( grayrow );
1066 break;
1067
1068 case PBM_TYPE:
1069 bitrow = pbm_allocrow( cols );
1070 if ( bitrow == (bit*) 0 )
1071 return -1;
1072 for ( col = 0, bP = bitrow, xP = xelrow; col < cols; ++col, ++bP, ++xP )
1073 *bP = PNM_GET1( *xP ) == 0 ? PBM_BLACK : PBM_WHITE;
1074 pbm_writepbmrow( file, bitrow, cols, forceplain );
1075 pbm_freerow( bitrow );
1076 break;
1077
1078 default:
1079 (void) fprintf( stderr, "%s: can't happen\n", progname );
1080 return -1;
1081 }
1082 return 0;
1083 }
1084
1085 #if __STDC__
1086 int
1087 pnm_writepnm( FILE* file, xel** xels, int cols, int rows, xelval maxval, int format, int forceplain )
1088 #else /*__STDC__*/
1089 int
1090 pnm_writepnm( file, xels, cols, rows, maxval, format, forceplain )
1091 FILE* file;
1092 xel** xels;
1093 xelval maxval;
1094 int cols, rows, format;
1095 int forceplain;
1096 #endif /*__STDC__*/
1097 {
1098 int row;
1099
1100 if ( pnm_writepnminit( file, cols, rows, maxval, format, forceplain ) < 0 )
1101 return -1;
1102
1103 for ( row = 0; row < rows; ++row )
1104 if ( pnm_writepnmrow( file, xels[row], cols, maxval, format, forceplain ) < 0 )
1105 return -1;
1106 return 0;
1107 }
1108
1109
1110 /* Colormap stuff. */
1111
1112 #define HASH_SIZE 20023
1113
1114 #define ppm_hashpixel(p) ( ( ( (long) PPM_GETR(p) * 33023 + (long) PPM_GETG(p) * 30013 + (long) PPM_GETB(p) * 27011 ) & 0x7fffffff ) % HASH_SIZE )
1115
1116 colorhist_vector
1117 ppm_computecolorhist( pixels, cols, rows, maxcolors, colorsP )
1118 pixel** pixels;
1119 int cols, rows, maxcolors;
1120 int* colorsP;
1121 {
1122 colorhash_table cht;
1123 colorhist_vector chv;
1124
1125 cht = ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP );
1126 if ( cht == (colorhash_table) 0 )
1127 return (colorhist_vector) 0;
1128 chv = ppm_colorhashtocolorhist( cht, maxcolors );
1129 ppm_freecolorhash( cht );
1130 return chv;
1131 }
1132
1133 void
1134 ppm_addtocolorhist( chv, colorsP, maxcolors, colorP, value, position )
1135 colorhist_vector chv;
1136 pixel* colorP;
1137 int* colorsP;
1138 int maxcolors, value, position;
1139 {
1140 int i, j;
1141
1142 /* Search colorhist for the color. */
1143 for ( i = 0; i < *colorsP; ++i )
1144 if ( PPM_EQUAL( chv[i].color, *colorP ) )
1145 {
1146 /* Found it - move to new slot. */
1147 if ( position > i )
1148 {
1149 for ( j = i; j < position; ++j )
1150 chv[j] = chv[j + 1];
1151 }
1152 else if ( position < i )
1153 {
1154 for ( j = i; j > position; --j )
1155 chv[j] = chv[j - 1];
1156 }
1157 chv[position].color = *colorP;
1158 chv[position].value = value;
1159 return;
1160 }
1161 if ( *colorsP < maxcolors )
1162 {
1163 /* Didn't find it, but there's room to add it; so do so. */
1164 for ( i = *colorsP; i > position; --i )
1165 chv[i] = chv[i - 1];
1166 chv[position].color = *colorP;
1167 chv[position].value = value;
1168 ++(*colorsP);
1169 }
1170 }
1171
1172 colorhash_table
1173 ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP )
1174 pixel** pixels;
1175 int cols, rows, maxcolors;
1176 int* colorsP;
1177 {
1178 colorhash_table cht;
1179 register pixel* pP;
1180 colorhist_list chl;
1181 int col, row, hash;
1182
1183 cht = ppm_alloccolorhash( );
1184 if ( cht == (colorhash_table) 0 )
1185 return (colorhash_table) 0;
1186 *colorsP = 0;
1187
1188 /* Go through the entire image, building a hash table of colors. */
1189 for ( row = 0; row < rows; ++row )
1190 for ( col = 0, pP = pixels[row]; col < cols; ++col, ++pP )
1191 {
1192 hash = ppm_hashpixel( *pP );
1193 for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
1194 if ( PPM_EQUAL( chl->ch.color, *pP ) )
1195 break;
1196 if ( chl != (colorhist_list) 0 )
1197 ++(chl->ch.value);
1198 else
1199 {
1200 if ( ++(*colorsP) > maxcolors )
1201 {
1202 ppm_freecolorhash( cht );
1203 return (colorhash_table) 0;
1204 }
1205 chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
1206 if ( chl == 0 )
1207 {
1208 (void) fprintf(
1209 stderr, "%s: out of memory computing hash table\n",
1210 progname );
1211 ppm_freecolorhash( cht );
1212 return (colorhash_table) 0;
1213 }
1214 chl->ch.color = *pP;
1215 chl->ch.value = 1;
1216 chl->next = cht[hash];
1217 cht[hash] = chl;
1218 }
1219 }
1220
1221 return cht;
1222 }
1223
1224 colorhash_table
1225 ppm_alloccolorhash( )
1226 {
1227 colorhash_table cht;
1228 int i;
1229
1230 cht = (colorhash_table) malloc( HASH_SIZE * sizeof(colorhist_list) );
1231 if ( cht == 0 )
1232 {
1233 (void) fprintf(
1234 stderr, "%s: out of memory allocating hash table\n", progname );
1235 return (colorhash_table) 0;
1236 }
1237
1238 for ( i = 0; i < HASH_SIZE; ++i )
1239 cht[i] = (colorhist_list) 0;
1240
1241 return cht;
1242 }
1243
1244 int
1245 ppm_addtocolorhash( cht, colorP, value )
1246 colorhash_table cht;
1247 pixel* colorP;
1248 int value;
1249 {
1250 register int hash;
1251 register colorhist_list chl;
1252
1253 chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
1254 if ( chl == 0 )
1255 return -1;
1256 hash = ppm_hashpixel( *colorP );
1257 chl->ch.color = *colorP;
1258 chl->ch.value = value;
1259 chl->next = cht[hash];
1260 cht[hash] = chl;
1261 return 0;
1262 }
1263
1264 colorhist_vector
1265 ppm_colorhashtocolorhist( cht, maxcolors )
1266 colorhash_table cht;
1267 int maxcolors;
1268 {
1269 colorhist_vector chv;
1270 colorhist_list chl;
1271 int i, j;
1272
1273 /* Now collate the hash table into a simple colorhist array. */
1274 chv = (colorhist_vector) malloc( maxcolors * sizeof(struct colorhist_item) );
1275 /* (Leave room for expansion by caller.) */
1276 if ( chv == (colorhist_vector) 0 )
1277 {
1278 (void) fprintf(
1279 stderr, "%s: out of memory generating histogram\n", progname );
1280 return (colorhist_vector) 0;
1281 }
1282
1283 /* Loop through the hash table. */
1284 j = 0;
1285 for ( i = 0; i < HASH_SIZE; ++i )
1286 for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chl->next )
1287 {
1288 /* Add the new entry. */
1289 chv[j] = chl->ch;
1290 ++j;
1291 }
1292
1293 /* All done. */
1294 return chv;
1295 }
1296
1297 colorhash_table
1298 ppm_colorhisttocolorhash( chv, colors )
1299 colorhist_vector chv;
1300 int colors;
1301 {
1302 colorhash_table cht;
1303 int i, hash;
1304 pixel color;
1305 colorhist_list chl;
1306
1307 cht = ppm_alloccolorhash( );
1308 if ( cht == (colorhash_table) 0 )
1309 return (colorhash_table) 0;
1310
1311 for ( i = 0; i < colors; ++i )
1312 {
1313 color = chv[i].color;
1314 hash = ppm_hashpixel( color );
1315 for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
1316 if ( PPM_EQUAL( chl->ch.color, color ) )
1317 {
1318 (void) fprintf(
1319 stderr, "%s: same color found twice - %d %d %d\n", progname,
1320 PPM_GETR(color), PPM_GETG(color), PPM_GETB(color) );
1321 ppm_freecolorhash( cht );
1322 return (colorhash_table) 0;
1323 }
1324 chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
1325 if ( chl == (colorhist_list) 0 )
1326 {
1327 (void) fprintf( stderr, "%s: out of memory\n", progname );
1328 ppm_freecolorhash( cht );
1329 return (colorhash_table) 0;
1330 }
1331 chl->ch.color = color;
1332 chl->ch.value = i;
1333 chl->next = cht[hash];
1334 cht[hash] = chl;
1335 }
1336
1337 return cht;
1338 }
1339
1340 int
1341 ppm_lookupcolor( cht, colorP )
1342 colorhash_table cht;
1343 pixel* colorP;
1344 {
1345 int hash;
1346 colorhist_list chl;
1347
1348 hash = ppm_hashpixel( *colorP );
1349 for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
1350 if ( PPM_EQUAL( chl->ch.color, *colorP ) )
1351 return chl->ch.value;
1352
1353 return -1;
1354 }
1355
1356 void
1357 ppm_freecolorhist( chv )
1358 colorhist_vector chv;
1359 {
1360 free( (char*) chv );
1361 }
1362
1363 void
1364 ppm_freecolorhash( cht )
1365 colorhash_table cht;
1366 {
1367 int i;
1368 colorhist_list chl, chlnext;
1369
1370 for ( i = 0; i < HASH_SIZE; ++i )
1371 for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chlnext )
1372 {
1373 chlnext = chl->next;
1374 free( (char*) chl );
1375 }
1376 free( (char*) cht );
1377 }
1378
1379
1380
1381
1382 /* added from libpnm3.c: */
1383
1384 /* libpnm3.c - pnm utility library part 3
1385 **
1386 ** Copyright (C) 1989, 1991 by Jef Poskanzer.
1387 **
1388 ** Permission to use, copy, modify, and distribute this software and its
1389 ** documentation for any purpose and without fee is hereby granted, provided
1390 ** that the above copyright notice appear in all copies and that both that
1391 ** copyright notice and this permission notice appear in supporting
1392 ** documentation. This software is provided "as is" without express or
1393 ** implied warranty.
1394 */
1395
1396 #if __STDC__
1397 xel
1398 pnm_backgroundxel( xel** xels, int cols, int rows, xelval maxval, int format )
1399 #else /*__STDC__*/
1400 xel
1401 pnm_backgroundxel( xels, cols, rows, maxval, format )
1402 xel** xels;
1403 int cols, rows, format;
1404 xelval maxval;
1405 #endif /*__STDC__*/
1406 {
1407 xel bgxel, ul, ur, ll, lr;
1408
1409 /* Guess a good background value. */
1410 ul = xels[0][0];
1411 ur = xels[0][cols-1];
1412 ll = xels[rows-1][0];
1413 lr = xels[rows-1][cols-1];
1414
1415 /* First check for three corners equal. */
1416 if ( PNM_EQUAL( ul, ur ) && PNM_EQUAL( ur, ll ) )
1417 bgxel = ul;
1418 else if ( PNM_EQUAL( ul, ur ) && PNM_EQUAL( ur, lr ) )
1419 bgxel = ul;
1420 else if ( PNM_EQUAL( ul, ll ) && PNM_EQUAL( ll, lr ) )
1421 bgxel = ul;
1422 else if ( PNM_EQUAL( ur, ll ) && PNM_EQUAL( ll, lr ) )
1423 bgxel = ur;
1424 /* Nope, check for two corners equal. */
1425 else if ( PNM_EQUAL( ul, ur ) || PNM_EQUAL( ul, ll ) ||
1426 PNM_EQUAL( ul, lr ) )
1427 bgxel = ul;
1428 else if ( PNM_EQUAL( ur, ll ) || PNM_EQUAL( ur, lr ) )
1429 bgxel = ur;
1430 else if ( PNM_EQUAL( ll, lr ) )
1431 bgxel = ll;
1432 else
1433 {
1434 /* Nope, we have to average the four corners. This breaks the
1435 ** rules of pnm, but oh well. Let's try to do it portably. */
1436 switch ( PNM_FORMAT_TYPE(format) )
1437 {
1438 case PPM_TYPE:
1439 PPM_ASSIGN( bgxel,
1440 PPM_GETR(ul) + PPM_GETR(ur) + PPM_GETR(ll) + PPM_GETR(lr) / 4,
1441 PPM_GETG(ul) + PPM_GETG(ur) + PPM_GETG(ll) + PPM_GETG(lr) / 4,
1442 PPM_GETB(ul) + PPM_GETB(ur) + PPM_GETB(ll) + PPM_GETB(lr) / 4 );
1443 break;
1444
1445 case PGM_TYPE:
1446 {
1447 gray gul, gur, gll, glr;
1448 gul = (gray) PNM_GET1( ul );
1449 gur = (gray) PNM_GET1( ur );
1450 gll = (gray) PNM_GET1( ll );
1451 glr = (gray) PNM_GET1( lr );
1452 PNM_ASSIGN1( bgxel, ( ( gul + gur + gll + glr ) / 4 ) );
1453 break;
1454 }
1455
1456 case PBM_TYPE:
1457 pm_error(
1458 "pnm_backgroundxel: four bits no two of which equal each other??" );
1459
1460 default:
1461 pm_error( "can't happen" );
1462 }
1463 }
1464
1465 return bgxel;
1466 }
1467
1468 #if __STDC__
1469 xel
1470 pnm_backgroundxelrow( xel* xelrow, int cols, xelval maxval, int format )
1471 #else /*__STDC__*/
1472 xel
1473 pnm_backgroundxelrow( xelrow, cols, maxval, format )
1474 xel* xelrow;
1475 int cols, format;
1476 xelval maxval;
1477 #endif /*__STDC__*/
1478 {
1479 xel bgxel, l, r;
1480
1481 /* Guess a good background value. */
1482 l = xelrow[0];
1483 r = xelrow[cols-1];
1484
1485 /* First check for both corners equal. */
1486 if ( PNM_EQUAL( l, r ) )
1487 bgxel = l;
1488 else
1489 {
1490 /* Nope, we have to average the two corners. This breaks the
1491 ** rules of pnm, but oh well. Let's try to do it portably. */
1492 switch ( PNM_FORMAT_TYPE(format) )
1493 {
1494 case PPM_TYPE:
1495 PPM_ASSIGN( bgxel, PPM_GETR(l) + PPM_GETR(r) / 2,
1496 PPM_GETG(l) + PPM_GETG(r) / 2, PPM_GETB(l) + PPM_GETB(r) / 2 );
1497 break;
1498
1499 case PGM_TYPE:
1500 {
1501 gray gl, gr;
1502 gl = (gray) PNM_GET1( l );
1503 gr = (gray) PNM_GET1( r );
1504 PNM_ASSIGN1( bgxel, ( ( gl + gr ) / 2 ) );
1505 break;
1506 }
1507
1508 case PBM_TYPE:
1509 {
1510 int col, blacks;
1511
1512 /* One black, one white. Gotta count. */
1513 for ( col = 0, blacks = 0; col < cols; ++col )
1514 {
1515 if ( PNM_GET1( xelrow[col] ) == 0 )
1516 ++blacks;
1517 }
1518 if ( blacks >= cols / 2 )
1519 PNM_ASSIGN1( bgxel, 0 );
1520 else
1521 PNM_ASSIGN1( bgxel, pnm_pbmmaxval );
1522 break;
1523 }
1524
1525 default:
1526 pm_error( "can't happen" );
1527 }
1528 }
1529
1530 return bgxel;
1531 }
1532
1533 #if __STDC__
1534 xel
1535 pnm_whitexel( xelval maxval, int format )
1536 #else /*__STDC__*/
1537 xel
1538 pnm_whitexel( maxval, format )
1539 xelval maxval;
1540 int format;
1541 #endif /*__STDC__*/
1542 {
1543 xel x;
1544
1545 switch ( PNM_FORMAT_TYPE(format) )
1546 {
1547 case PPM_TYPE:
1548 PPM_ASSIGN( x, maxval, maxval, maxval );
1549 break;
1550
1551 case PGM_TYPE:
1552 PNM_ASSIGN1( x, maxval );
1553 break;
1554
1555 case PBM_TYPE:
1556 PNM_ASSIGN1( x, pnm_pbmmaxval );
1557 break;
1558
1559 default:
1560 pm_error( "can't happen" );
1561 }
1562
1563 return x;
1564 }
1565
1566 #if __STDC__
1567 xel
1568 pnm_blackxel( xelval maxval, int format )
1569 #else /*__STDC__*/
1570 xel
1571 pnm_blackxel( maxval, format )
1572 xelval maxval;
1573 int format;
1574 #endif /*__STDC__*/
1575 {
1576 xel x;
1577
1578 switch ( PNM_FORMAT_TYPE(format) )
1579 {
1580 case PPM_TYPE:
1581 PPM_ASSIGN( x, 0, 0, 0 );
1582 break;
1583
1584 case PGM_TYPE:
1585 PNM_ASSIGN1( x, (xelval) 0 );
1586 break;
1587
1588 case PBM_TYPE:
1589 PNM_ASSIGN1( x, (xelval) 0 );
1590 break;
1591
1592 default:
1593 pm_error( "can't happen" );
1594 }
1595
1596 return x;
1597 }
1598
1599 #if __STDC__
1600 void
1601 pnm_invertxel( xel* xP, xelval maxval, int format )
1602 #else /*__STDC__*/
1603 void
1604 pnm_invertxel( xP, maxval, format )
1605 xel* xP;
1606 xelval maxval;
1607 int format;
1608 #endif /*__STDC__*/
1609 {
1610 switch ( PNM_FORMAT_TYPE(format) )
1611 {
1612 case PPM_TYPE:
1613 PPM_ASSIGN(
1614 *xP, maxval - PPM_GETR( *xP ),
1615 maxval - PPM_GETG( *xP ), maxval - PPM_GETB( *xP ) );
1616 break;
1617
1618 case PGM_TYPE:
1619 PNM_ASSIGN1( *xP, (gray) maxval - (gray) PNM_GET1( *xP ) );
1620 break;
1621
1622 case PBM_TYPE:
1623 PNM_ASSIGN1( *xP, ( PNM_GET1( *xP ) == 0 ) ? pnm_pbmmaxval : 0 );
1624 break;
1625
1626 default:
1627 pm_error( "can't happen" );
1628 }
1629 }
1630
1631 #if __STDC__
1632 void
1633 pnm_promoteformat( xel** xels, int cols, int rows, xelval maxval, int format, xelval newmaxval, int newformat )
1634 #else /*__STDC__*/
1635 void
1636 pnm_promoteformat( xels, cols, rows, maxval, format, newmaxval, newformat )
1637 xel** xels;
1638 xelval maxval, newmaxval;
1639 int cols, rows, format, newformat;
1640 #endif /*__STDC__*/
1641 {
1642 int row;
1643
1644 for ( row = 0; row < rows; ++row )
1645 pnm_promoteformatrow(
1646 xels[row], cols, maxval, format, newmaxval, newformat );
1647 }
1648
1649 #if __STDC__
1650 void
1651 pnm_promoteformatrow( xel* xelrow, int cols, xelval maxval, int format, xelval newmaxval, int newformat )
1652 #else /*__STDC__*/
1653 void
1654 pnm_promoteformatrow( xelrow, cols, maxval, format, newmaxval, newformat )
1655 xel* xelrow;
1656 xelval maxval, newmaxval;
1657 int cols, format, newformat;
1658 #endif /*__STDC__*/
1659 {
1660 register int col;
1661 register xel* xP;
1662
1663 if ( ( PNM_FORMAT_TYPE(format) == PPM_TYPE &&
1664 ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE ||
1665 PNM_FORMAT_TYPE(newformat) == PBM_TYPE ) ) ||
1666 ( PNM_FORMAT_TYPE(format) == PGM_TYPE &&
1667 PNM_FORMAT_TYPE(newformat) == PBM_TYPE ) )
1668 pm_error( "pnm_promoteformatrow: can't promote downwards!" );
1669
1670 /* Are we promoting to the same type? */
1671 if ( PNM_FORMAT_TYPE(format) == PNM_FORMAT_TYPE(newformat) )
1672 {
1673 if ( PNM_FORMAT_TYPE(format) == PBM_TYPE )
1674 return;
1675 if ( newmaxval < maxval )
1676 pm_error(
1677 "pnm_promoteformatrow: can't decrease maxval - try using pnmdepth" );
1678 if ( newmaxval == maxval )
1679 return;
1680 /* Increase maxval. */
1681 switch ( PNM_FORMAT_TYPE(format) )
1682 {
1683 case PGM_TYPE:
1684 for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
1685 PNM_ASSIGN1(
1686 *xP, (int) PNM_GET1(*xP) * newmaxval / maxval );
1687 break;
1688
1689 case PPM_TYPE:
1690 for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
1691 PPM_DEPTH( *xP, *xP, maxval, newmaxval );
1692 break;
1693
1694 default:
1695 pm_error( "shouldn't happen" );
1696 }
1697 return;
1698 }
1699
1700 /* We must be promoting to a higher type. */
1701 switch ( PNM_FORMAT_TYPE(format) )
1702 {
1703 case PBM_TYPE:
1704 switch ( PNM_FORMAT_TYPE(newformat) )
1705 {
1706 case PGM_TYPE:
1707 for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
1708 if ( PNM_GET1(*xP) == 0 )
1709 PNM_ASSIGN1( *xP, 0 );
1710 else
1711 PNM_ASSIGN1( *xP, newmaxval );
1712 break;
1713
1714 case PPM_TYPE:
1715 for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
1716 if ( PNM_GET1(*xP) == 0 )
1717 PPM_ASSIGN( *xP, 0, 0, 0 );
1718 else
1719 PPM_ASSIGN( *xP, newmaxval, newmaxval, newmaxval );
1720 break;
1721
1722 default:
1723 pm_error( "can't happen" );
1724 }
1725 break;
1726
1727 case PGM_TYPE:
1728 switch ( PNM_FORMAT_TYPE(newformat) )
1729 {
1730 case PPM_TYPE:
1731 if ( newmaxval < maxval )
1732 pm_error(
1733 "pnm_promoteformatrow: can't decrease maxval - try using pnmdepth" );
1734 if ( newmaxval == maxval )
1735 {
1736 for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
1737 PPM_ASSIGN(
1738 *xP, PNM_GET1(*xP), PNM_GET1(*xP), PNM_GET1(*xP) );
1739 }
1740 else
1741 { /* Increase maxval. */
1742 for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
1743 PPM_ASSIGN(
1744 *xP, (int) PNM_GET1(*xP) * newmaxval / maxval,
1745 (int) PNM_GET1(*xP) * newmaxval / maxval,
1746 (int) PNM_GET1(*xP) * newmaxval / maxval );
1747 }
1748 break;
1749
1750 default:
1751 pm_error( "can't happen" );
1752 }
1753 break;
1754
1755 default:
1756 pm_error( "can't happen" );
1757 }
1758 }