🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: alt.graphics.pixutils
1 messages
1 total messages Started by David Clunie Fri, 22 Jul 1994 18:40
PATCH: netpbm/pbmplus 16 bit raw files
#706
Author: David Clunie
Date: Fri, 22 Jul 1994 18:40
371 lines
13582 bytes
Raw 16 bit read/write patch for pbmplus.10dec91 and netpbm-13oct93.

This patches pgm and ppm libraries and derived utilities to read and
write raw binary files that use 16 bit words when maxval is >255 rather
than the default behaviour of switching from raw byte output to plain text
output in this case.

The patches are essentially trivial and don't break anything, except that
such files will not be portable to unpatched versions of pbmplus, but
then almost no-one uses the pgm/ppm formats for 12 or 16 bit data since
the plain text output is so big ... at least not till now :)

While I could have defined new 'Pn' tags for different formats, which
probably would have made unpatched versions of pbmplus die more gracefully
on encountering them, the existing code uses the "maxval <= 255" decision
in all the right places and it was considerably tidier to do it this way.

I also had to define a byte order convention, so I chose little endian
arbitrarily. This is not selfish performance seeking as most of my machines
are big endian anyway !

I hope this convention will be widely adopted and included in the next
netpbm release so that the issue can be quietly forgotten about forever.

This patch was developed for use in medical imaging applications as an
intermediate image format for a DICOM 3 project, and for use with JPEG
12 bit processes (there will be an accompanying patch for the IJG JPEG code
to do the same thing).

david (dclunie@flash.us.com)

To apply this patch, change to the directory netpbm or whatever you have
called it and pipe this file to 'patch -p1'.

Note that this works fine for netpbm-13oct93. For pbmplus.10dec91 it will
reject one part of the patch to pgm/libpgm2.c and ppm/libppm2.c because
there is no " {" after "    if ( maxval <= 255 && ! forceplain )" at
line 34 ... you need to change the patch accordingly (remove the " {")
in both the from/to parts of the patch before applying it, and then
everything works ok. (This all because somebody extended the initialize
routine to set_outfile_binary() for VMS and needed more than a single
statement after the decision ... that wonderful and joyous operating
system strikes once again).

diff -r -c netpbm/pbmplus.h netpbm.rawword/pbmplus.h
*** netpbm/pbmplus.h	Fri Jul 22 02:22:14 1994
--- netpbm.rawword/pbmplus.h	Fri Jul 22 02:36:44 1994
***************
*** 55,60 ****
--- 55,71 ----
  */
  #define PBMPLUS_RAWBITS
  
+ /* CONFIGURE: If you want to "raw" files with 16 bits, set this option.
+ ** The read and write routines then assume that anything with maxval
+ ** > 255 needs a raw word and not just a byte in the input or output.
+ ** The byte-order convention for words is little-endian. Note that any
+ ** pbm tools not compiled with this option will freak if offered such files
+ ** subsequently. Only applicable with PBMPLUS_RAWBITS and PGM_BIGGRAYS.
+ ** The normal behaviour is to use plain text output if maxval > 255.
+ ** One can still force plain text output with pnmnoraw.
+ */
+ #define PBMPLUS_RAWWORDS
+ 
  /* CONFIGURE: PGM can store gray values as either bytes or shorts.  For most
  ** applications, bytes will be big enough, and the memory savings can be
  ** substantial.  However, if you need more than 8 bits of grayscale resolution,
diff -r -c netpbm/pgm/libpgm1.c netpbm.rawword/pgm/libpgm1.c
*** netpbm/pgm/libpgm1.c	Fri Jul 22 02:03:32 1994
--- netpbm.rawword/pgm/libpgm1.c	Fri Jul 22 02:13:19 1994
***************
*** 105,111 ****
--- 105,122 ----
  	case RPGM_FORMAT:
  	for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
  	    {
+ #ifdef PBMPLUS_RAWWORDS
+ 	    if ( maxval <= 255 )
+ 	        *gP = pbm_getrawbyte( file );
+ 	    else
+ 	        {
+ 	        short s;
+ 	        (void) pm_readlittleshort( file, &s );
+ 	        *gP = s;
+ 	        }
+ #else  /*PBMPLUS_RAWWORDS*/
  	    *gP = pbm_getrawbyte( file );
+ #endif /*PBMPLUS_RAWWORDS*/
  #ifdef DEBUG
  	    if ( *gP > maxval )
  		pm_error( "value out of bounds (%u > %u)", *gP, maxval );
diff -r -c netpbm/pgm/libpgm2.c netpbm.rawword/pgm/libpgm2.c
*** netpbm/pgm/libpgm2.c	Fri Jul 22 02:03:35 1994
--- netpbm.rawword/pgm/libpgm2.c	Fri Jul 22 02:03:35 1994
***************
*** 31,37 ****
--- 31,41 ----
  #endif /*__STDC__*/
      {
  #ifdef PBMPLUS_RAWBITS
+ #ifdef PBMPLUS_RAWWORDS
+     if ( ! forceplain ) {
+ #else  /*PBMPLUS_RAWWORDS*/
      if ( maxval <= 255 && ! forceplain ) {
+ #endif /*PBMPLUS_RAWWORDS*/
  	fprintf(
  	    file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, RPGM_MAGIC2,
  	    cols, rows, maxval );
***************
*** 77,83 ****
--- 81,94 ----
  	if ( *gP > maxval )
  	    pm_error( "value out of bounds (%u > %u)", *gP, maxval );
  #endif /*DEBUG*/
+ #ifdef PBMPLUS_RAWWORDS
+ 	if ( maxval <= 255 )
+ 	    (void) putc( *gP, file );
+ 	else
+ 	    (void) pm_writelittleshort( file, (short) *gP );
+ #else  /*PBMPLUS_RAWWORDS*/
  	(void) putc( *gP, file );
+ #endif /*PBMPLUS_RAWWORDS*/
  	}
      }
  #endif /*PBMPLUS_RAWBITS*/
***************
*** 130,136 ****
--- 141,151 ----
  #endif /*__STDC__*/
      {
  #ifdef PBMPLUS_RAWBITS
+ #ifdef PBMPLUS_RAWWORDS
+     if ( ! forceplain )
+ #else  /*PBMPLUS_RAWWORDS*/
      if ( maxval <= 255 && ! forceplain )
+ #endif /*PBMPLUS_RAWWORDS*/
  	pgm_writepgmrowraw( file, grayrow, cols, maxval );
      else
  	pgm_writepgmrowplain( file, grayrow, cols, maxval );
diff -r -c netpbm/pgm/pgm.5 netpbm.rawword/pgm/pgm.5
*** netpbm/pgm/pgm.5	Fri Jul 22 02:45:35 1994
--- netpbm.rawword/pgm/pgm.5	Fri Jul 22 02:48:45 1994
***************
*** 59,76 ****
  .IP - 2
  The "magic number" is "P5" instead of "P2".
  .IP - 2
! The gray values are stored as plain bytes, instead of ASCII decimal.
  .IP - 2
  No whitespace is allowed in the grays section, and only a single character
  of whitespace (typically a newline) is allowed after the maxval.
  .IP - 2
  The files are smaller and many times faster to read and write.
  .PP
- Note that this raw format can only be used for maxvals less than
- or equal to 255.
  If you use the
  .I pgm
! library and try to write a file with a larger maxval,
  it will automatically fall back on the slower but more general plain
  format.
  .SH "SEE ALSO"
--- 59,81 ----
  .IP - 2
  The "magic number" is "P5" instead of "P2".
  .IP - 2
! The gray values are stored as plain bytes, instead of ASCII decimal, if
! maxvals are less than or equal to 255.
  .IP - 2
+ If they are larger than 255, then
+ if the RAWWORDS option has been set at compile time, they will be written
+ as two plain bytes in little-endian byte order. Note that this is a
+ recent change in format and may not be portable.
+ .IP - 2
  No whitespace is allowed in the grays section, and only a single character
  of whitespace (typically a newline) is allowed after the maxval.
  .IP - 2
  The files are smaller and many times faster to read and write.
  .PP
  If you use the
  .I pgm
! library and try to write a file with a larger maxval than 255, and the RAWWORDS
! option has not been set at compile time, 
  it will automatically fall back on the slower but more general plain
  format.
  .SH "SEE ALSO"
diff -r -c netpbm/ppm/libppm1.c netpbm.rawword/ppm/libppm1.c
*** netpbm/ppm/libppm1.c	Fri Jul 22 02:13:04 1994
--- netpbm.rawword/ppm/libppm1.c	Fri Jul 22 02:13:04 1994
***************
*** 125,141 ****
--- 125,174 ----
  	case RPPM_FORMAT:
  	for ( col = 0, pP = pixelrow; col < cols; ++col, ++pP )
  	    {
+ #ifdef PBMPLUS_RAWWORDS
+ 	    if ( maxval <= 255 )
+ 	        r = pbm_getrawbyte( file );
+ 	    else
+ 	        {
+ 	        short s;
+ 	        (void) pm_readlittleshort( file, &s );
+ 	        r = s;
+ 	        }
+ #else  /*PBMPLUS_RAWWORDS*/
  	    r = pbm_getrawbyte( file );
+ #endif /*PBMPLUS_RAWWORDS*/
  #ifdef DEBUG
  	    if ( r > maxval )
  		pm_error( "r value out of bounds (%u > %u)", r, maxval );
  #endif /*DEBUG*/
+ #ifdef PBMPLUS_RAWWORDS
+ 	    if ( maxval <= 255 )
+ 	        g = pbm_getrawbyte( file );
+ 	    else
+ 	        {
+ 	        short s;
+ 	        (void) pm_readlittleshort( file, &s );
+ 	        g = s;
+ 	        }
+ #else  /*PBMPLUS_RAWWORDS*/
  	    g = pbm_getrawbyte( file );
+ #endif /*PBMPLUS_RAWWORDS*/
  #ifdef DEBUG
  	    if ( g > maxval )
  		pm_error( "g value out of bounds (%u > %u)", g, maxval );
  #endif /*DEBUG*/
+ #ifdef PBMPLUS_RAWWORDS
+ 	    if ( maxval <= 255 )
+ 	        b = pbm_getrawbyte( file );
+ 	    else
+ 	        {
+ 	        short s;
+ 	        (void) pm_readlittleshort( file, &s );
+ 	        b = s;
+ 	        }
+ #else  /*PBMPLUS_RAWWORDS*/
  	    b = pbm_getrawbyte( file );
+ #endif /*PBMPLUS_RAWWORDS*/
  #ifdef DEBUG
  	    if ( b > maxval )
  		pm_error( "b value out of bounds (%u > %u)", b, maxval );
diff -r -c netpbm/ppm/libppm2.c netpbm.rawword/ppm/libppm2.c
*** netpbm/ppm/libppm2.c	Fri Jul 22 02:08:34 1994
--- netpbm.rawword/ppm/libppm2.c	Fri Jul 22 02:08:34 1994
***************
*** 31,37 ****
--- 31,41 ----
  #endif /*__STDC__*/
      {
  #ifdef PBMPLUS_RAWBITS
+ #ifdef PBMPLUS_RAWWORDS
+     if ( ! forceplain ) {
+ #else  /*PBMPLUS_RAWWORDS*/
      if ( maxval <= 255 && ! forceplain ) {
+ #endif /*PBMPLUS_RAWWORDS*/
  	fprintf(
  	    file, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, RPPM_MAGIC2,
  	    cols, rows, maxval );
***************
*** 79,97 ****
--- 83,122 ----
  	if ( val > maxval )
  	    pm_error( "r value out of bounds (%u > %u)", val, maxval );
  #endif /*DEBUG*/
+ #ifdef PBMPLUS_RAWWORDS
+ 	if ( maxval <= 255 )
+ 	    (void) putc( val, file );
+ 	else
+ 	    (void) pm_writelittleshort( file, (short) val );
+ #else  /*PBMPLUS_RAWWORDS*/
  	(void) putc( val, file );
+ #endif /*PBMPLUS_RAWWORDS*/
  	val = PPM_GETG( *pP );
  #ifdef DEBUG
  	if ( val > maxval )
  	    pm_error( "g value out of bounds (%u > %u)", val, maxval );
  #endif /*DEBUG*/
+ #ifdef PBMPLUS_RAWWORDS
+ 	if ( maxval <= 255 )
+ 	    (void) putc( val, file );
+ 	else
+ 	    (void) pm_writelittleshort( file, (short) val );
+ #else  /*PBMPLUS_RAWWORDS*/
  	(void) putc( val, file );
+ #endif /*PBMPLUS_RAWWORDS*/
  	val = PPM_GETB( *pP );
  #ifdef DEBUG
  	if ( val > maxval )
  	    pm_error( "b value out of bounds (%u > %u)", val, maxval );
  #endif /*DEBUG*/
+ #ifdef PBMPLUS_RAWWORDS
+ 	if ( maxval <= 255 )
+ 	    (void) putc( val, file );
+ 	else
+ 	    (void) pm_writelittleshort( file, (short) val );
+ #else  /*PBMPLUS_RAWWORDS*/
  	(void) putc( val, file );
+ #endif /*PBMPLUS_RAWWORDS*/
          }
      }
  #endif /*PBMPLUS_RAWBITS*/
***************
*** 161,167 ****
--- 186,196 ----
  #endif /*__STDC__*/
      {
  #ifdef PBMPLUS_RAWBITS
+ #ifdef PBMPLUS_RAWWORDS
+     if ( ! forceplain )
+ #else  /*PBMPLUS_RAWWORDS*/
      if ( maxval <= 255 && ! forceplain )
+ #endif /*PBMPLUS_RAWWORDS*/
  	ppm_writeppmrowraw( file, pixelrow, cols, maxval );
      else
  	ppm_writeppmrowplain( file, pixelrow, cols, maxval );
diff -r -c netpbm/ppm/ppm.5 netpbm.rawword/ppm/ppm.5
*** netpbm/ppm/ppm.5	Fri Jul 22 02:48:44 1994
--- netpbm.rawword/ppm/ppm.5	Fri Jul 22 02:48:44 1994
***************
*** 58,75 ****
  .IP - 2
  The "magic number" is "P6" instead of "P3".
  .IP - 2
! The pixel values are stored as plain bytes, instead of ASCII decimal.
  .IP - 2
  Whitespace is not allowed in the pixels area, and only a single character
  of whitespace (typically a newline) is allowed after the maxval.
  .IP - 2
  The files are smaller and many times faster to read and write.
  .PP
- Note that this raw format can only be used for maxvals less than
- or equal to 255.
  If you use the
  .I ppm 
! library and try to write a file with a larger maxval,
  it will automatically fall back on the slower but more general plain
  format.
  .SH "SEE ALSO"
--- 58,80 ----
  .IP - 2
  The "magic number" is "P6" instead of "P3".
  .IP - 2
! The pixel values are stored as plain bytes, instead of ASCII decimal, if
! maxvals are less than or equal to 255
  .IP - 2
+ If they are larger than 255, then
+ if the RAWWORDS option has been set at compile time, they will be written
+ as two plain bytes in little-endian byte order. Note that this is a
+ recent change in format and may not be portable.
+ .IP - 2
  Whitespace is not allowed in the pixels area, and only a single character
  of whitespace (typically a newline) is allowed after the maxval.
  .IP - 2
  The files are smaller and many times faster to read and write.
  .PP
  If you use the
  .I ppm 
! library and try to write a file with a larger maxval than 255, and the RAWWORDS
! option has not been set at compile time, 
  it will automatically fall back on the slower but more general plain
  format.
  .SH "SEE ALSO"


---
David A. Clunie (dclunie@flash.us.com)
In sunny Riyadh, Saudi Arabia.

"I must see your DICOM 3 conformance statement before I buy."
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads