home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / graphics.formats / hdf / NCSA_HDF / HDF.2.ascii.Z / HDF.2.ascii
Encoding:
Text File  |  1991-09-24  |  32.5 KB  |  814 lines

  1. 2.1NCSA HDF Calling Interfaces and Utilities
  2.  
  3. Storing Raster Images2.1
  4.  
  5. National Center for Supercomputing Applications
  6.  
  7. November 1989
  8.  
  9.  
  10.  
  11.  
  12.  
  13. 2.1NCSA HDF Calling Interfaces and Utilities
  14.  
  15. Storing Raster Images2.1
  16.  
  17. National Center for Supercomputing Applications
  18.  
  19. November 1989
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28. Chapter 2Storing Raster Images
  29.  
  30.  
  31.  
  32. Chapter Overview
  33. Header Files
  34. Raster Image Sets
  35. Reasons to Use Raster Image Sets
  36. 8-Bit Raster Image Sets
  37. Compression Schemes
  38. Writing 8-Bit Raster Images to a File
  39. Reading 8-Bit Raster Images from a File
  40. 24-Bit Raster Image Sets
  41. Interlace Schemes
  42. Compression Schemes
  43. Writing 24-Bit Raster Images to a File
  44. Reading 24-Bit Raster Images from a File
  45. Sample Programs
  46. A FORTRAN Program to Copy a RIS8 from One File to Another
  47. A C Program to Convert a Raw Palette and Raw Raster Image to HDF RIS8 Format
  48. C Functions to Convert Floating-Point Data to
  49. 8-Bit Raster Data
  50.  
  51. Chapter Overview
  52.  
  53. This chapter discusses the purposes and use of raster image sets, which allow you to store an image, together with its dimensions and a palette, in an HDF file. This chapter specifically introduces and describes the two raster image set interfaces currently contained in the HDF library:  RIS8 and RIS24.
  54.  
  55. Header Files
  56.  
  57. The header file dfrig.h contains the declarations and definitions that are used by the routines listed in this chapter. This file can, if needed, be included with your C source code, and in some cases also with FORTRAN code.
  58.  
  59.  
  60. Raster Image Sets
  61.  
  62. A raster image set (RIS) is a set of tags and associated information required to store an image in an HDF file. In HDF, 8-bit raster image sets (RIS8) are used to store 8-bit raster images, and 24-bit raster image sets (RIS24) are used to store 24-bit raster images.
  63.  
  64. The HDF library currently contains routines for storing raw raster images in RIS8 or RIS24 format and for retrieving raster images from files containing raster image sets. These routines are callable from C and FORTRAN programs that have access to the library. They work on several computers, including Cray systems running UNICOS, Alliant, Vax, Sun, and Macintosh models. 
  65.  
  66. Table 2.1 lists the long and short names and the functions of the RIS8 and RIS24 routines currently contained in the HDF library. The following sections provide descriptions and examples of these calling routines.
  67.  
  68. Table 2.1Raster Image Set Routines in the HDF Library
  69. Long NameShort NameFunction
  70.  
  71. DFR8setpaletted8spalsets the default palette to be used for subsequent images.
  72.  
  73. DFR8putimaged8pimgwrites out the RIS8 for the image as the first image in the file.
  74.  
  75. DFR8addimaged8aimgappends the RIS8 for the image to the file.
  76.  
  77. DFR8getdimsd8gdimsretrieves the dimensions of the image and indicates whether a palette is associated and stored with the image.
  78.  
  79. Table 2.1Raster Image Set Routines in the HDF Library (Continued)
  80. Long NameShort NameFunction
  81.  
  82. DFR8getimaged8gimgretrieves the image and any associated palette, and stores them in arrays.
  83.  
  84. DFR8restartd8firstgets the next get command to read from the first RIS8 in the file, rather than the next.
  85.  
  86.  
  87. DF24setild2setilsets the interlace to be used when writing out the RIS24 for the image.
  88.  
  89. DF24addimaged2iaimgappends the RIS24 for the image to the file.
  90.  
  91. DF24getdimsd2igdimsretrieves the dimensions and interlace of the image.
  92.  
  93. DF24getimaged2igimgretrieves the image and stores it in an array.
  94.  
  95. DF24reqil(il)d2reqilspecifies an interlace to be used in place of the interlace indicated in the file when the next raster image is read.
  96.  
  97.  
  98. Reasons to Use Raster Image Sets
  99.  
  100. When raster images are stored in the form of HDF raster image sets, it becomes possible to use a variety of software tools for displaying and manipulating them. NCSA Image, for instance, can operate directly on images stored in HDF raster image format. Other software can display raster images in HDF format on a variety of different machines.
  101.  
  102. By using HDF files with raster image sets, programmers are able to write portable software for working with the images much more easily than otherwise. When palette, dimension, or compression information is stored in the same file as the actual images, the software does not have to search elsewhere for this pertinent information. More importantly, you may be spared from having to supply the information. This reduction in the need to coordinate disparate pieces of information about a raster image can make the job of creating and running image-processing programs significantly easier.
  103.  
  104.  
  105. 8-Bit Raster Image Sets
  106.  
  107. The phrase, 8-bit raster image set (RIS8), refers to the set of tags and associated information required to store an 8-bit raster image in an HDF file. An RIS8 contains at least the first three of the following components and may also contain a palette:
  108.  
  109. ÑAn image-here, a two-dimensional array of 8-bit numbers, one for each pixel in the raster image, where pixel values range from 0 to 255 (Pixel values indicate to the hardware which colors to use when drawing the corresponding pixels on the screen.)
  110.  
  111. ÑDimensions-two values that represent the x and y dimensions of the image, respectively
  112.  
  113. ÑA compression scheme-a code that indicates if and how the image was compressed (See the following section, "Compression Schemes.╙)
  114.  
  115. ÑA palette-a lookup table with 256 entries that tells the color to associate with each of the 256 possible pixel values (Each entry in the palette is chosen from a master palette of 224 RGB colors. Each palette entry consists of three bytes, one each for red, green, and blue. The first three bytes represent the R, G, and B values of the first color in the palette; the next three the R, G, and B values of the second color; and so forth. The total size of a palette is 768 bytes.)
  116.  
  117. An example of an HDF file with two raster image sets is illustrated in Figure 2.1.
  118.  
  119. Figure 2.1Two Raster Image Sets in an HDF File
  120.  
  121.  
  122.  
  123. Compression Schemes
  124. A compression scheme indicates if and how an image is compressed. Compression schemes currently supported by NCSA HDF are run length encoding and IMCOMP. The value of the integer argument compress determines which scheme, if any, is to be used, as shown in Table 2.2.
  125.  
  126. Table 2.2Compression Scheme Codes
  127. ValueCompression Scheme
  128. 0none
  129. DFTAG_RLErun length encoding (RLE)
  130. DFTAG_IMCOMPIMCOMP
  131.  
  132. The HDF tags DFTAG_RLE and DFTAG_IMCOMP are defined as the values 11 and 12, respectively, in the file 'df.h'. You can avoid using numbers for compression codes if you include this file in your program.
  133.  
  134.  
  135. A Note About RLE
  136. The run length encoding (RLE) method used in HDF works as follows:  Each sequence of pixels begins with a count byte. The low seven bits of the count byte indicate the number of bytes in the sequence (n). The high bit of the count byte indicates whether the next byte should be replicated n times (high bit=1), or whether the next n bytes should be included as is (high bit=0).
  137.  
  138. The amount of space saved by RLE depends upon how much repetition there is among the pixels in the rows. (Pixels are stored in rows.) If there is a great deal of repetition, much space is saved; if there is little repetion, the savings can be very small. In the worst case-when every pixel is different from the one that precedes it-an extra byte is added for every 127 bytes in the image.
  139.  
  140.  
  141. A Note About IMCOMP
  142. IMCOMP should be used with caution if you are concerned about losing information in your image. IMCOMP compression first breaks an image into 4 x 4 arrays of pixels, then for each array chooses two colors to distribute in the array. (These two colors are added to a 256-color palette that IMCOMP compression builds. This new palette is based on, but different from, the original palette assigned.) Each of the 16 pixels in the 4 x 4 array can now be represented by one bit (0=first color; 1=second color). In addition to these sixteen bits, there are two bytes that give the palette locations of the two colors that were assigned to the 4 x 4 array.
  143.  
  144. Since each 4 x 4 array uses only 4 bytes, IMCOMP stores an image at a cost of 2 bits per pixel, which is 25% of the original storage requirement for the 8-bit image. The drawback of this savings is loss of information-only two colors are allowed to occupy each 4 X 4 array of pixels-whereas in the original image, 16 colors could occupy the same space. For many images this cost is bearable and hardly noticable, but for some images, the results can be totally unrecognizable.
  145.  
  146. Also note that IMCOMP is dependent on the existence of a palette. If you are going to use IMCOMP, you must include a palette with your image.
  147.  
  148.  
  149. Writing 8-Bit Raster Images to a File
  150. DFR8setpalette
  151. FORTRAN:
  152. INTEGER FUNCTION DFR8setpalette(palette)
  153.  
  154. CHARACTER*1palette(768)-palette to go with image
  155.  
  156. C:
  157. int DFR8setpalette(palette)
  158.  
  159. unsigned charpalette[768];/* palette to go with image */
  160.  
  161. Purpose:  To indicate what palette, if any, is to be used for subsequent images.
  162.  
  163. Returns:  0 on success; -1 on failure.
  164.  
  165. The palette that is set here continues as the default palette until it is changed by a new call to the routine.
  166.  
  167.  
  168. DFR8putimage
  169. FORTRAN:
  170. INTEGER FUNCTION DFR8putimage(filename, image, xdim, ydim, compress)
  171.  
  172. CHARACTER*64filename-name of file to store RIS8 in
  173. INTEGERxdim, ydim-dimensions of image
  174. CHARACTERimage(xdim,ydim)-array holding image to be put in file
  175. INTEGERcompress-type of compression to use, if
  176. any
  177.  
  178. C:
  179. int DFR8putimage(filename, image, xdim, ydim, compress)
  180.  
  181. char*filename;/* name of file to store RIS8 in */
  182. int32xdim, ydim;/* dimensions of image */
  183. char*image;/* array with image to put in file */
  184. intcompress;/* type of compression to use, if any */
  185.  
  186. Purpose:  To write out the RIS8 for the image as the first image in the file.
  187.  
  188. Returns:  0 on success; -1 on failure.
  189.  
  190. If before the call to DFR8putimage there was other information in the file, the function overwrites that information.
  191.  
  192. The argument compress identifies the scheme to be used for compressing the data, if any. Refer to Table 2.2 for valid values of compress.
  193.  
  194. If IMCOMP compression is used, the image must include a palette. (See the discussion of 8-bit compression schemes in an earlier section.)
  195.  
  196. NOTE:  DFR8addimage (see below) writes an image to a file by appending it, rather than overwriting it.
  197.  
  198.  
  199. DFR8addimage
  200. FORTRAN:
  201. INTEGER FUNCTION DFR8addimage(filename,image,xdim,ydim, compress)
  202.  
  203. CHARACTER*64filename-name of file to add RIS8 to 
  204. INTEGERxdim, ydim-dimensions of the image 
  205. CHARACTERimage(xdim,ydim) -array holding image to be added 
  206. to file 
  207. INTEGERcompress-type of compression to use, if 
  208. any
  209.  
  210. C:
  211. int DFR8addimage(filename,image,xdim,ydim,compress)
  212.  
  213. char*filename;/*  name of file to add RIS8 to */
  214. int32xdim, ydim;/* dimensions of the image */
  215. char*image;/* array holding image to add to file */
  216. intcompress;/* type of compression to use, if any */
  217.  
  218. Purpose:  To append to the file the RIS8 for the image.
  219.  
  220. Returns:  0 on success; -1 on failure.
  221.  
  222. In all other respects, DFR8addimage is functionally equivalent to DFR8putimage.
  223.  
  224.  
  225. Example:  Writing a Palette and an Image in RIS8 Format
  226. Figure 2.2 demonstrates in FORTRAN how a palette stored in the array colors and a raw image stored in the 400 x 600 array picture are written to a file in RIS8 format.
  227.  
  228. Figure 2.2Storing an RIS8
  229. FORTRAN:
  230. INTEGERDFR8setpalette, DFR8putimage
  231. CHARACTER*1colors(768)
  232. CHARACTER*1picture(400,600)
  233. INTEGERret
  234.  
  235. ret = DFR8setpalette(colors)
  236. ret = DFR8putimage('herfile.hdf',picture,400,600,0)
  237.  
  238. if (ret .ne. 0)
  239. write(*,*) 'Error writing image to myfile.hdf.'
  240.   .
  241.   .
  242.   .
  243.  
  244.  
  245. Remarks:
  246.  
  247. ÑThe RIS8 with this palette and image is stored as the first image in 'herfile.hdf'. Note that if something already existed in this file, it will be lost.
  248.  
  249. ÑThe image is not compressed in the file.
  250.  
  251. ÑThe palette is assumed to be organized in the manner described earlier:  R, G, B (first color); R, G, B (second color); and so forth.
  252.  
  253.  
  254. Example:  Writing a Series of RIS8 Images
  255. Figure 2.3 illustrates a series of FORTRAN calls in which four 800 x 1200 images are written to the same file. The first two use palette palA and are compressed using the IMCOMP technique; the third and fourth use palette palB and are not compressed.
  256.  
  257. Figure 2.3Storing Multiple RIS8s in a Single File
  258. FORTRAN:
  259. INTEGERDFR8setpalette, DFR8putimage, DFR8addimage
  260. CHARACTER*1palA(768), palB(768)
  261. CHARACTER*1pic1(800,1200), pic2(800,1200)
  262. CHARACTER*1pic3(800,1200), pic4(800,1200)
  263. INTEGERret
  264.  
  265. INTEGERDFTAG_IMCOMP
  266. DATADFTAG_IMCOMP/12/
  267.  
  268. ret = DFR8setpalette(palA)
  269. ret = DFR8putimage('myfile',pic1,800,1200,DFTAG_IMCOMP)
  270. ret = DFR8addimage('myfile',pic2,800,1200,DFTAG_IMCOMP)
  271. ret = DFR8setpalette(palB)
  272. ret = DFR8addimage('myfile',pic3,800,1200,0)
  273. ret = DFR8addimage('myfile',pic4,800,1200,0)
  274.   .
  275.   .
  276.   .
  277.  
  278. Reading 8-Bit Raster Images from a File
  279. The two routines, DFR8getdims and DFR8getimage, are sufficient to read raster images from a file. If enough is known about the images and palettes, only the latter routine is needed.
  280.  
  281.  
  282. DFR8getdims
  283. FORTRAN:
  284. INTEGER FUNCTION DFR8getdims(filename,xdim,ydim,ispalette)
  285.  
  286. CHARACTER*64filename-name of file with RIS8 image
  287. INTEGERxdim, ydim-dimensions of the next image
  288. INTEGERispalette-1 if there is a palette, else 0
  289.  
  290. C:
  291. int DFR8getdims(filename,xdim,ydim,ispalette)
  292.  
  293. char *filename;/*  name of file with RIS8 image */
  294. int32*xdim, *ydim;/*  dimensions of the next image */
  295. int*ispalette;/*  1 if there is a palette, else 0 */
  296.  
  297. Purpose:  To open the file with name filename, find the next image, retrieve the dimensions of the image in xdim and ydim, and tell, via ispalette, whether there is a palette associated with the image.
  298.  
  299. Returns:  0 on success; -1 on failure.
  300.  
  301. If the file is being opened for the first time, DFR8getdims returns information about the first image in the file. If an image has already been read, DFR8getdims finds the next image. Thus, images are read in the same order in which they were written to the file.
  302.  
  303. Normally, DFR8getdims is called before DFR8getimage so that if necessary, space allocations for the image and palette can be checked, and the dimensions can be verified. If this information is already known, DFR8getdims need not be called.
  304.  
  305.  
  306. DFR8getimage
  307. FORTRAN:
  308. INTEGER FUNCTION DFR8getimage(filename, image, xdim, ydim, palette)
  309.  
  310. CHARACTER*64filename-name of file with RIS8 image
  311. INTEGERxdim,ydim-dimensions of the next image
  312. CHARACTER*1 image(xdim,ydim)  -array that will hold the image
  313. CHARACTER*1 palette(768)-palette to go with image
  314.  
  315. C:
  316. int DFR8getimage(filename, image, xdim, ydim, palette)
  317.  
  318. char *filename;/* name of file with RIS8 image */
  319. int32xdim, ydim;/* dimensions of the next image */
  320. char*image;/* array that will hold image */
  321. unsigned char*palette;/* palette to go with image */
  322.  
  323. Purpose:  To retrieve the image and its palette, if it is present, and store them in the specified arrays.
  324.  
  325. Returns:  0 on success; -1 on failure.
  326.  
  327. If palette is NULL, no palette is loaded, even if there is one stored with the image. If the image in the file is compressed, DFR8getimage automatically decompresses it.
  328.  
  329. If DFR8getdims has not been called, DFR8getimage finds the next image in the same way that DFR8getdims does.
  330.  
  331.  
  332. DFR8restart
  333. FORTRAN:
  334. INTEGER FUNCTION DFR8restart()
  335.  
  336. C:
  337. int DFR8restart()
  338.  
  339. Purpose:  To cause the next get to read from the first RIS8 in the file, rather than the RIS8 following the one that was most recently read
  340.  
  341. Returns:  0 on success; -1 on failure
  342.  
  343.  
  344. Example:  Reading in a Raster Image Set
  345. Figure 2.4 shows a FORTRAN call that reads in an image when the dimensions are already known, and a palette is known to exist.
  346.  
  347. Figure 2.4Reading an RIS8:  Dimensions and Presence of Palette Known
  348. FORTRAN:
  349. INTEGERDFR8getimage
  350. CHARACTER*1image(256,512)
  351. CHARACTER*1palette(768)
  352. INTEGERret
  353.  
  354. ret = DFR8getimage('myfile.hdf',image,256,512,pal)
  355.   .
  356.   .
  357.   .
  358.  
  359. Remarks:
  360.  
  361. ÑThe RIS8, stored in a file called, 'myfile.hdf', is read into an array called image.
  362.  
  363. ÑThe raster image stored in the file is known to be 256 x 512 bytes.
  364.  
  365. ÑThe array image is a 256x512 array of 8-bit characters. It is assumed that the array is dimensioned to be exactly this size.
  366.  
  367. ÑThe parameter pal is a 768-byte array, three bytes per color, representing R, G, and B values, respectively, for each color.
  368.  
  369. ÑIf DFR8getimage executes successfully, the return value 0 is assigned to ret; otherwise, ╨1 is assigned.
  370.  
  371.  
  372. Example:  Reading in a Raster Image Set
  373. Figure 2.5 demonstrates a pair of  FORTRAN calls in which the size of the image is not known ahead of time, nor is it known whether a palette exists.
  374.  
  375. Figure 2.5Reading an RIS8:  Dimensions and Presence of Palette Not Known
  376. FORTRAN:
  377. INTEGERDFR8getdims, DFR8getimage
  378. INTEGERxsize, ysize, ispal, ret
  379. CHARACTER*1image(xsize,ysize)
  380. CHARACTER*1pal(768)
  381.  
  382. ret = DFR8getdims('myfile.hdf',xsize,ysize,ispal)
  383. ret = DFR8getimage('myfile.hdf',image,xsize,ysize,pal)
  384.   .
  385.   .
  386.   .
  387.  
  388.  
  389. Remarks:
  390.  
  391. ÑThe RIS8, stored in a file called, 'myfile.hdf', is read into an array called image.
  392.  
  393. ÑIf after calling DFR8getdims, ispal is 1, then the call to DFR8getimage causes a palette to be loaded into the array pal. If the value of ispal is not 1, then nothing is loaded into the array pal when DFR8getimage is called. If a palette is needed, then the program has to supply it.
  394.  
  395. ÑThe array image is an xsize x ysize array of 8-bit characters. It is assumed that the array is dimensioned to be exactly this size.
  396.  
  397. 24-Bit Raster Image Sets
  398.  
  399. The phrase 24-bit raster image set (RIS24) refers to the set of tags and associated information required to store a 24-bit raster image in an HDF file. An RIS24 contains at least the following components:
  400.  
  401. ÑAn image-here, a two-dimensional array of 24-bit pixel representations, where each 24-bit pixel value has three 8-bit components:  one each for the red, green, and blue (RGB) values of the pixel color. These RGB values may be arranged in the file in one of three different ways (see the following section, "Interlace Schemes").
  402.  
  403. ÑAn interlace scheme-a code that describes the order in which the pixel components are physically stored in the file (see the following section, "Interlace Schemes").
  404.  
  405. ÑDimensions-two values that represent the x and y dimensions of the image, respectively.
  406.  
  407.  
  408. Interlace Schemes
  409. An interlace scheme describes the way an image is stored in a file or in memory. NCSA HDF supports different interlace schemes because graphics applications and devices vary in the way they organize graphics images. By storing an image in a file using a scheme that is consistent with the expected application or device, you can achieve substantial improvements in performance. The value of the integer argument il determines which scheme is to be used, as shown in Table 2.3. The interlace schemes are described in the following sections.
  410.  
  411. Table 2.3Interlace Scheme Codes
  412. Value of ilInterlace Scheme
  413. 0pixel
  414. 1scan-line
  415. 2scan-plane
  416.  
  417.  
  418. Pixel Interlace Scheme
  419. The default interlace scheme describes an image pixel-by-pixel. This scheme is called pixel interlace. The code to specify the pixel interlace scheme in an RIS24 is 0 (zero).
  420.  
  421. For example, by default, NCSA HDF assumes that a 100 x 200 image with three components (R, G, and B) is stored as an array of size 3 x 100 x 200, and that each element of this array is exactly one byte in size and contains an R, G, or B value.
  422.  
  423. Specifically, an interlace code of 0 indicates that the bytes that describe the image are stored in the following order in the file or memory:  
  424.  
  425. R,  G, and B values are stored, in that order, in the first three bytes of the first row of the array, corresponding to the first pixel in the first row of the image.
  426.  
  427. R, G, and B values are stored in the second three bytes of the first row of the array, corresponding to the second pixel in the first row of the image.
  428.  
  429. And so forth, until the RGB values for the 100 pixels of the first row of the image are stored.  This process is repeated until the RGB values for each pixel in the 200 lines of the image are stored.
  430.  
  431.  
  432. Scan-Line Interlace Scheme
  433. The scan-line interlace scheme describes an image line-by-line. The code to specify the scan-line interlace scheme is 1.
  434.  
  435. For example, an interlace scheme code of 1 for a 100 x 200 image with three components (R, G, and B) informs NCSA HDF to assume that the image is stored as an array of size 100 x 3 x 200.
  436.  
  437. Specifically, an interlace code of 1 indicates that the bytes that describe the image are stored in the following order in the file or memory:  100 R values are stored consecutively in the first row of the array for each of the pixels in the first line of the image, then 100 G values are stored in the second row of the array for each of the pixels in the first line of the image, then 100 B values are stored in the third row of the array for each of the pixels in the first line of the image, and so forth, until the RGB values for each of the 200 lines of pixels in the image are stored.
  438.  
  439.  
  440. Scan-Plane Interlace Scheme
  441. The scan-plane interlace scheme describes an image color component-by-color component. The code to specify the scan-plane interlace scheme is 2.
  442.  
  443. For example, an interlace scheme code of 2 for a 100 x 200 image with three components (R, G, and B) informs NCSA HDF to assume that the image is stored as an array of size 100 x 200 x 3.
  444.  
  445. Specifically, an interlace code of 2 indicates that the bytes that describe the image are stored in the following order in the file or memory:  R values are stored in the first 100 x 200 bytes of the array for each of the pixels in the image; the G values for the image are stored in the second 100 x 200 plane; and the B values in the third.
  446.  
  447. Figure 2.6 illustrates how an RIS24 -- stored using the scan-plane interlace -- looks in an HDF file.
  448.  
  449. Figure 2.6Scan-Plane Interlace
  450.  
  451.  
  452.  
  453. Compression Schemes
  454. As of this writing, image compression has not been implemented for 24-bit images in HDF. However, there are plans to implement a routine to cause 24-bit images to be stored in compressed mode. This routine should be available in the next release of HDF.
  455.  
  456.  
  457. Writing 24-Bit Raster Images to a File
  458. DF24setil
  459. FORTRAN:
  460. INTEGER FUNCTION DF24setil(il)
  461.  
  462. INTEGER il;- interlace of image 
  463. C:
  464. int DF24setil(il)
  465.  
  466. int il;/* interlace of image */
  467.  
  468.  
  469. Purpose:  To set interlace scheme to be used on subsequent writes.
  470.  
  471. Returns:  0 on success; ╨1 on failure with DFerror set.
  472.  
  473. If DF24setil is not called, the interlace code is assumed to be 0. Interlace codes: 0 = pixel interlacing; 1 = scan-line interlacing; 
  474. 2 = scan-plane interlacing.
  475.  
  476.  
  477. DF24addimage 
  478. FORTRAN:
  479. INTEGER FUNCTION DF24addimage(name, image, xdim, ydim)
  480. CHARACTER*(*) name
  481. CHARACTER *(*)image
  482. INTEGER xdim, ydim
  483. C:
  484. int DF24addimage(filename, image, xdim, ydim)
  485. char *filename;/* name of HDF file */
  486. char *image;/* pointer to space for return image */
  487. int32 xdim, ydim;/* dimensions of array image */
  488.  
  489.  
  490. Purpose:  To write out a 24-bit image.
  491.  
  492. Returns:  0 on success; ╨1 on failure with DFerror set.
  493.  
  494. Array image is assumed to be xdim x ydim x 3 bytes.
  495.  
  496.  
  497. Example:  Writing a RIS24  with the Default Pixel Interlace
  498. The C code in Figure 2.7 demonstrates how the default pixel interlace is used when storing the 400 x 600 array picture in a file in RIS24 format.
  499.  
  500. Figure 2.7Storing an RIS24 Using Pixel Interlace
  501. C:
  502. intDF24putimage;
  503. char*picture[3][400][600];
  504. intret;
  505.  
  506. ret = DF24addimage("herfile.hdf",picture,400,600);
  507.  
  508. if (ret != 0)
  509.     printf("Error writing image to myfile.hdf.");
  510.   .
  511.   .
  512.   .
  513.  
  514.  
  515. Example:  Writing Several 24-bit Images
  516. Figure 2.8 shows a series of C calls in which four 800 x 1200 images are written to the same file. The first two calls use the default interlace scheme; the second two calls use scan-line interlace.
  517.  
  518. Figure 2.8Storing Multiple RIS24s in a Single File
  519. C:
  520. intDF24addimage
  521. charpic1[3][800][1200], pic2[3][800][1200]
  522. charpic3[800][3][1200], pic4[800][3][1200]
  523.  
  524. DF24addimage('myfile',pic1,800,1200)
  525. DF24addimage('myfile',pic2,800,1200)
  526. DF24setil(1)
  527. DF24addimage('myfile',pic3,800,1200)
  528. DF24addimage('myfile',pic4,800,1200)
  529.   .
  530.   .
  531.   .
  532.  
  533.  
  534. Reading 24-Bit Raster Images from a File
  535. The two routines, DF24getdims and DF24getimage, are sufficient to read raster images from a file. If enough is known about the images and interlacing, only the latter routine is needed.
  536.  
  537.  
  538. DF24getdims
  539.  
  540. FORTRAN:
  541. INTEGER FUNCTION DF24getdims(name, xdim, ydim, il)
  542. CHARACTER*(*) name-name of HDF file
  543. INTEGER xdim, ydim-for returning x & y dimensions 
  544. INTEGER il-for returning interlace of image in file 
  545. C:
  546. int DF24getdims(filename, pxdim, pydim, pil)
  547. char *filename;/* name of HDF file */
  548. int32 *pxdim, *pydim;/* pointers to locations for returning
  549. x & y dimensions */
  550. int *pil;/* location for returning interlace
  551. of image in file */
  552.  
  553. Purpose:  To get dimensions and interlace storage scheme of next image RIS.
  554.  
  555. Returns:  0 on success; ╨1 on failure with DFerror set.
  556.  
  557. If the file is being opened for the first time, DF24getdims returns information about the first image in the file. If an image has already been read, DF24getdims finds the next image. Thus, images are read in the same order in which they were written to the file.
  558.  
  559. If you know the dimensions of the image beforehand, there is no need to call DF24getdims. Simply allocate arrays with the proper dimensions for the image and let DF24getimage read in the images. If, however, you do not know the values of rows and cols, you must call DF24getdims to get them and then use them to determine the right amount of space needed for the array image.
  560.  
  561. Successive additional calls to DF24getdims and DF24getimage, respectively, retrieve all of the images in the file in the sequence in which they were written.
  562.  
  563. Interlace codes: 0 = pixel interlacing; 1 = scan-line interlacing; 
  564. 2 = scan-plane interlacing.
  565.  
  566.  
  567. DF24getimage
  568. FORTRAN:
  569. INTEGER FUNCTION DF24getimage(name, image, xdim, ydim)
  570. CHARACTER*(*) name-name of HDF file
  571. CHARACTER*(*) image-pointer to space to return image
  572. INTEGER xdim, ydim-dimensions of space to return image
  573. C:
  574. int DF24getimage(filename, image, xdim, ydim)
  575. char *filename;/* name of HDF file */
  576. char *image;/* pointer to space to return image */
  577. int32 xdim, ydim;/* dimensions of space to return lut */
  578. Purpose:  To get image from next RIS.
  579.  
  580. Returns:  0 on success; ╨1 on failure with DFerror set.
  581.  
  582. If DFR8getdims has not been called, DFR8getimage finds the next image in the same way that DFR8getdims does.
  583.  
  584. The amount of space allocated for the image should be xdim x Idim x 3 bytes.
  585.  
  586. To specify that the next call to DF24getimage should read the raster image from the RIS24 using a particular interlace, rather than the interlace used to store the image in the file, make a call to DF24reqil (see below).
  587. DF24reqil
  588. FORTRAN:
  589. INTEGER FUNCTION DF24reqil(il)
  590. INTEGER il- interlace to get next image with
  591. C:
  592. int DF24reqil(il)
  593. int il;/* interlace to get next image with */
  594.  
  595.  
  596. Purpose:  To cause next  DF24getimage to store image with the specified interlace.
  597.  
  598. Returns:  0 on success; ╨1 on failure with DFerror set.
  599.  
  600. Regardless of what interlace scheme is used to store the image, DF24reqil causes the image to be loaded into memory, interlaced according to the specification of il.
  601.  
  602. NOTE:  Since a call to DF24reqil may require a substantial reordering of the data, I/O performance could be adversely affected; e.g. it could result in much slower I/O performance than would be achieved if no change in interlace were requested.
  603.  
  604. Interlace codes:  0 = pixel interlacing; 1 = scan-line interlacing; 
  605. 2 = scan-plane interlacing.
  606.  
  607.  
  608. Example:  Reading in a 24-bit Image
  609. Figure 2.9 shows a C call that reads in an image when the dimensions and interlace are already known.
  610.  
  611. Figure 2.9Reading an RIS24:  Dimensions and Interlace Known
  612. C:
  613. intDF24getimage;
  614. charimage[3][256][512];
  615.  
  616. DF24getimage("myfile.hdf",image,256,512);
  617.   .
  618.   .
  619.   .
  620.  
  621.  
  622. Remarks:
  623.  
  624. ÑThe RIS8, stored in a file called 'myfile.hdf', is read into an array called image.
  625.  
  626. ÑThe raster image stored in the file is known to be 256 x 512.
  627.  
  628. ÑThe array image is a 3 x 256 x 512 array of 8-bit characters.
  629.  
  630.  
  631. Example:  Read an Image, Dimensions and Interlace Not Known
  632. Figure 2.10 illustrates a set of C calls that read in an image, where the dimensions of the image and interlace scheme are not known ahead of time.
  633.  
  634. Figure 2.10Reading an RIS24:  Dimensions and Interlace Not Known
  635. C:
  636. intDF24getdims, DF24getimage;
  637. intxsize, ysize, ispal;
  638. char*image;  /* pointer to space to return image */
  639.  
  640. DF24getdims("myfile.hdf",xsize,ysize,il);
  641. DF24reqil(2);
  642. image = (char *) malloc(3*xsize*ysize);
  643. DF24getimage("myfile.hdf",image,xsize,ysize);
  644.   .
  645.   .
  646.   .
  647.  
  648.  
  649. Remarks:
  650.  
  651. ÑThe RIS24 is stored in a file called 'myfile.hdf' in an array called image.
  652.  
  653. ÑThe data is stored in the array image as if the array were three planes of size xsize x ysize.
  654.  
  655. ÑSince no explicit declaration is given for image, it is the responsibility of the program to compute offsets in the array that correspond to particular elements.
  656.  
  657.  
  658. Sample Programs
  659.  
  660. A FORTRAN Program to Copy a RIS8 from One File to Another
  661. This program reads into image1 an 8-bit raster image from an HDF file called 'testrig1.df'. At the same time, it reads a palette into the array palette. The dimensions of the image are read into rows and cols. It is assumed that the image is small enough to fit into the 150,000-character array image1; that is, the value rows*cols must be less than 150,000.
  662.  
  663. The program next writes out the palette and image to the file 'testrig2.df'. Since the compress parameter in DFR8putimage is 12, the output image is encoded using run length encoding. 
  664. (See Figure 2.11)
  665.  
  666. Figure 2.11 FORTRAN Program  to Copy a RIS8 from One File to Another
  667. FORTRAN:
  668. PROGRAM RISexample
  669.  
  670. CHARACTER*1image1(150000)
  671. CHARACTER*1palette(768)
  672. INTEGERrows, cols, ispal
  673. INTEGER ret
  674.  
  675.  
  676. ret = DFR8getdims('testrig1.df', rows, cols, ispal)
  677. ret = DFR8getimage('testrig1.df', image1, rows, cols, palette)
  678.  
  679. ret = DFR8setpalette(palette);
  680. ret = DFR8putimage('testrig2.df',image1,rows,cols,12)
  681.  
  682. stop
  683. end
  684.  
  685.  
  686. A C Program to Convert a Raw Palette and Raw Raster Image to HDF RIS8 Format
  687. The example in Figure 2.12 shows a complete program for processing RIS8 data. Several features of HDF image storage are illustrated here. The program does the following, in order:
  688.  
  689. ÑReads into image1 a 256 x 512 8-bit raster image from a non-HDF file called "denaa031"
  690.  
  691. ÑReads into each of red, green, and blue 256 values representing the palette from a file called "ps.pal" (The palette stored in "ps.pal" is not in HDF format, so it is rearranged into proper format in a new, 768-byte array called palette.)
  692.  
  693. ÑWrites the palette and image as a raster image set to a file called "testrig1.hdf"
  694.  
  695. ÑReads the palette and image back in, this time storing the image in image2 and storing the palette back in palette
  696.  
  697. ÑCompares the contents of image2 to the contents of image1 to determine whether they are identical, as they should be
  698.  
  699.  
  700. Figure 2.12  C Program Dealing with Raster Image Sets
  701.  
  702. C:
  703. #include "df.h"
  704.  
  705. main
  706. {
  707. unsigned char 
  708. image1[131072], /* raw image to be read in from denaa031,
  709.    then put into an RIS8 in testrig.df */
  710. image2[131072], /* image to be read in from testrig.df */
  711. palette[768], 
  712. reds[256], /* colors to be loaded into palette*/
  713. greens[256], 
  714. blues[256],
  715. *p;/* pointer to palette*/
  716. int j;
  717. int rows, cols, 
  718. ispal;/* boolean to tell if there is a palette*/
  719. FILE *fp;
  720.  
  721. fp = fopen("denaa031","r");  /* read in raw 256x512 image */
  722. fread(image1, 131072, 1, fp);
  723. fclose(fp);
  724. fp = fopen("ps.pal","r");/* read RGB values from palette file */
  725. fread(reds,1,256,fp);
  726. fread(greens,1,256,fp);
  727. fread(blues,1,256,fp);
  728. fclose(fp);
  729.  
  730. p = palette;
  731. for (j=0; j<256; j++) {/* reorganize palette so that */
  732. *p++ = reds[j];/* RGB values are interleaved */
  733. *p++ = greens[j];
  734. *p++ = blues[j];
  735. }
  736.  
  737. printf("Ready to write out image \n");
  738. DFR8setpalette(palette);
  739. DFR8putimage("testrig1.df",image1,256,512,DFTAG_RLE);
  740. printf("Just wrote out image \n");
  741.  
  742. DFR8getdims("testrig1.df",&rows, &cols, &ispal);
  743. printf("After getdim\n");
  744. printf("\tdimensions:%d :%d\n\tispal: %d\n", rows,cols,ispal);
  745. DFR8getimage("testrig1.df",image2,rows,cols,palette);
  746. printf("After getimage ... ");
  747. if (strncmp(image1, image2, 131072) ==0) printf("identical\n");
  748. else printf("different\n");
  749. }
  750.  
  751. C Functions to  Convert Floating-Point Data to
  752. 8-Bit Raster Data
  753. The two functions shown in Figure 2.13 convert a floating-point data array into an 8-bit raster array. Once converted, this raw raster array is ready to be stored in RIS8 format.
  754.  
  755.  
  756. Figure 2.13Converting Floating-Point Data to RIS8
  757. C:
  758. /* floattor8.c
  759.  */
  760. #include "df.h"
  761.  
  762. #define CHAR_MAX255
  763.  
  764. /*
  765.  * floattoR8
  766.  * Convert a data array into a raster array by dividing the
  767.  * range in the data into 256 regions, numbering  the regions 
  768.  * from zero to 255, and assigning to each position in the 
  769.  * raster array the number of the corresponding region.
  770.  *
  771.  * Assume that raster array allocated is big enough.
  772.  */
  773. floattoR8(data, raster, size, max, min)
  774. float data[];
  775. char  raster[];
  776. int   size;
  777. float max, min;
  778. {
  779.   int32 i;
  780.   float32 step;
  781.  
  782.   if ((max == 0) && (min == 0))
  783.     findMaxMin(data, size, &max, &min);
  784.  
  785.   step = (max - min) / CHAR_MAX;
  786.   if (step == 0)
  787.     return(-1);
  788.  
  789.   for(i=0;i<size;i++)
  790.     raster[i] = (char) ((data[i] - min) / step);
  791. }
  792.  
  793. /*
  794.  * findMaxMin
  795.  * Finds the maximum and minimum values in a data array.
  796.  */
  797. findMaxMin(data, size, max, min)
  798. float32 data[];
  799. int32 size;
  800. float32 *max, *min;
  801. {
  802.   int32 i;
  803.  
  804.   *max = *min = data[0];
  805.   for(i=1;i<size;i++) {
  806.     if (*max < data[i])
  807.       *max = data[i];
  808.     else if (*min > data[i])
  809.       *min = data[i];
  810.   }
  811. }
  812.  
  813.  
  814.