Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
buildmap.c
Go to the documentation of this file.
1 /*
2  * This software is copyrighted as noted below. It may be freely copied,
3  * modified, and redistributed, provided that the copyright notice is
4  * preserved on all copies.
5  *
6  * There is no warranty or other guarantee of fitness for this software,
7  * it is provided solely "as is". Bug reports or fixes may be sent
8  * to the author, who may or may not act on them as he desires.
9  *
10  * You may not include this software in a program or other software product
11  * without supplying the source, or without informing the end-user that the
12  * source is available for no extra charge.
13  *
14  * If you modify this software, you should include a notice giving the
15  * name of the person performing the modification, the date of modification,
16  * and the reason for such modification.
17  */
18 /*
19  * buildmap.c - Build a color map from the RLE file color map.
20  *
21  * Author: Spencer W. Thomas
22  * Computer Science Dept.
23  * University of Utah
24  * Date: Sat Jan 24 1987
25  * Copyright (c) 1987, University of Utah
26  */
27 
28 #include <stdio.h>
29 #include "rle.h"
30 #include <math.h>
31 
32 /*****************************************************************
33  * TAG( buildmap )
34  *
35  * Returns a color map that can easily be used to map the pixel values in
36  * an RLE file. Map is built from the color map in the input file.
37  * Inputs:
38  * the_hdr: rle_hdr structure containing color map.
39  * minmap: Minimum number of channels in output map.
40  * orig_gamma: Adjust color map for this image gamma value
41  * (1.0 means no adjustment).
42  * new_gamma: Gamma of new display.
43  * Outputs:
44  * Returns an array of pointers to arrays of rle_pixels. The array
45  * of pointers contains max(ncolors, ncmap) elements, each
46  * array of pixels contains 2^cmaplen elements. The pixel arrays
47  * should be considered read-only.
48  * Assumptions:
49  * [None]
50  * Algorithm:
51  * Ensure that there are at least ncolors rows in the map, and
52  * that each has at least 256 elements in it (largest map that can
53  * be addressed by an rle_pixel).
54  */
55 rle_pixel **
57 rle_hdr *the_hdr;
58 int minmap;
59 double orig_gamma;
60 double new_gamma;
61 {
62  rle_pixel ** cmap, * gammap;
63  double gamma;
64  register int i, j;
65  int maplen, cmaplen, nmap;
66 
67  if ( the_hdr->ncmap == 0 ) /* make identity map */
68  {
69  nmap = (minmap < the_hdr->ncolors) ? the_hdr->ncolors : minmap;
70  cmap = (rle_pixel **)malloc( nmap * sizeof(rle_pixel *) );
71  cmap[0] = (rle_pixel *)malloc( nmap * 256 * sizeof(rle_pixel) );
72  for ( j = 1; j < nmap; j++ )
73  cmap[j] = cmap[j-1] + 256;
74  for ( i = 0; i < 256; i++ )
75  for ( j = 0; j < nmap; j++ )
76  cmap[j][i] = i;
77  maplen = 256;
78  }
79  else /* make map from the_hdr */
80  {
81  /* Map is at least 256 long */
82  cmaplen = (1 << the_hdr->cmaplen);
83  if ( cmaplen < 256 )
84  maplen = 256;
85  else
86  maplen = cmaplen;
87 
88  /* Nmap is max( minmap, the_hdr->ncmap, the_hdr->ncolors ). */
89  nmap = minmap;
90  if ( nmap < the_hdr->ncmap )
91  nmap = the_hdr->ncmap;
92  if ( nmap < the_hdr->ncolors )
93  nmap = the_hdr->ncolors;
94 
95  /* Allocate memory for the map and secondary pointers. */
96  cmap = (rle_pixel **)malloc( nmap * sizeof(rle_pixel *) );
97  cmap[0] = (rle_pixel *)malloc( nmap * maplen * sizeof(rle_pixel) );
98  for ( i = 1; i < nmap; i++ )
99  cmap[i] = cmap[0] + i * maplen;
100 
101  /* Fill it in. */
102  for ( i = 0; i < maplen; i++ )
103  {
104  for ( j = 0; j < the_hdr->ncmap; j++ )
105  if ( i < cmaplen )
106  cmap[j][i] = the_hdr->cmap[j*cmaplen + i] >> 8;
107  else
108  cmap[j][i] = i;
109  for ( ; j < nmap; j++ )
110  cmap[j][i] = cmap[j-1][i];
111  }
112  }
113 
114  /* Gamma compensate if requested */
115  if ( orig_gamma == 0 )
116  {
117  char *v;
118  if ( (v = rle_getcom( "image_gamma", the_hdr )) != NULL )
119  {
120  orig_gamma = atof( v );
121  /* Protect against bogus information */
122  if ( orig_gamma == 0.0 )
123  orig_gamma = 1.0;
124  else
125  orig_gamma = 1.0 / orig_gamma;
126  }
127  else if ( (v = rle_getcom( "display_gamma", the_hdr )) != NULL)
128  {
129  orig_gamma = atof( v );
130  /* Protect */
131  if ( orig_gamma == 0.0 )
132  orig_gamma = 1.0;
133  }
134  else
135  orig_gamma = 1.0;
136  }
137 
138  /* Now, compensate for the gamma of the new display, too. */
139  if ( new_gamma != 0.0 )
140  gamma = orig_gamma / new_gamma;
141  else
142  gamma = orig_gamma;
143 
144  if ( gamma != 1.0 )
145  {
146  gammap = (rle_pixel *)malloc( 256 * sizeof(rle_pixel) );
147  for ( i = 0; i < 256; i++ )
148  gammap[i] = (int)(0.5 + 255.0 * pow( i / 255.0, gamma ));
149  for ( i = 0; i < nmap; i++ )
150  for ( j = 0; j < maplen; j++ )
151  cmap[i][j] = gammap[cmap[i][j]];
152  free( gammap );
153  }
154 
155  return cmap;
156 }
rle_map * cmap
Definition: rle.h:112
rle_pixel ** buildmap(rle_hdr *the_hdr, int minmap, double orig_gamma, double new_gamma)
Definition: buildmap.c:56
char * rle_getcom(char *name, rle_hdr *the_hdr) const
Definition: rle_getcom.c:81
int ncmap
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
int cmaplen
Definition: rle.h:100
int ncolors
Definition: rle.h:100