1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF. The full HDF copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /* $Id$ */
15 #include "hdf.h"
16 #ifndef I860
17 #include <stdlib.h>
18 #include <string.h>
19 #endif /* I860 */
20
21 /* Exception checking macro */
22 #define EXCHECK(a,b) if(a) goto b
23
24 /* Static variables */
25 uint8 red_comp[256], green_comp[256], blue_comp[256];
26
27 comp_info cinfo; /* compression structure */
28
29 static intn
30 magnify(uint8 *from_buffer, uint8 *to_buffer, int32 from_x0,
31 int32 from_y0, int32 from_x1, int32 from_y1, int32 from_width,
32 int32 from_height, int32 to_width, int32 to_height);
33
34 static intn
35 convert8to24(uint8 *img8_buf, uint8 *img24_buf, int32 img_xdim,
36 int32 img_ydim);
37
38 static VOID usage(void);
39
40 /**********************************************************************
41 * Function : magnify
42 * Purpose : Magnify an image by independant X and Y magnification
43 * factors. Note that the coordinates which specify
44 * the area in the "from" image are _inclusive_, i.e.
45 * if you would like to magnify the entire image, the
46 * "from" coordinates should be specified as:
47 * (0,0) and ((width-1),(height-1)), where "width"
48 * and "height" are the width and height of the image
49 * (respectively) in pixels.
50 * Parameters :
51 * from_buffer - pointer to the buffer which contains the image
52 * to magnify
53 * to_buffer - pointer to the buffer in which to place the
54 * magnified image
55 * from_x0, from_y0 - Upper Left Corner (ULC) of the rectangular
56 * area in the image to magnify
57 * from_x1, from_y1 - Lower Right Corner (LRC) of the rectangular
58 * area in the image to magnify
59 * from_width, from_height - the width and height of the image
60 * to magnify (or "from" image)
61 * to_width, to_height - the width and height of the magnified
62 * image (or "to" image)
63 * Returns : (TRUE) for success, (FALSE) for error
64 * Calls :
65 * Called by :
66 **********************************************************************/
67 static intn
magnify(uint8 * from_buffer,uint8 * to_buffer,int32 from_x0,int32 from_y0,int32 from_x1,int32 from_y1,int32 from_width,int32 from_height,int32 to_width,int32 to_height)68 magnify(uint8 *from_buffer, uint8 *to_buffer, int32 from_x0,
69 int32 from_y0, int32 from_x1, int32 from_y1, int32 from_width,
70 int32 from_height, int32 to_width, int32 to_height)
71 {
72 uint8 *buf_off, /* the current offset into the magnified data */
73 *last_buf, /* pointer to the last useful magnified line */
74 *y_off, /* the y offset into the data block */
75 *last_y_coor, /* pointer to the last line copied */
76 **y_coor; /* pointers to image data */
77 float64 temp_val, /* temporary value for holding double results */
78 wind_width, /* the width of the window to magnify */
79 wind_height; /* the height of the window to magnify */
80 int32 u, v; /* local unsigned counting variables */
81 int32 *x_coor, /* the X coor. lookup table */
82 *x_coor_temp; /* temporary pointer to the x lookup table */
83
84 if (from_width == 0 || from_height == 0) /* check for bad image dimensions */
85 return (FALSE);
86 if (to_width == 0 || to_height == 0) /* check for bad image dimensions */
87 return (FALSE);
88 if (from_x0 > from_x1 || from_y0 > from_y1) /* check for an invalid window */
89 return (FALSE);
90
91 /* find width and height of the window to magnify */
92 wind_width = (float64)((from_x1 - from_x0) + 1);
93 wind_height = (float64)((from_y1 - from_y0) + 1);
94
95 /* allocate room for the x coordinate lookup table */
96 x_coor = (int32 *) HDmalloc((int32) ((size_t)to_width * sizeof(int32)));
97 EXCHECK(x_coor == NULL, XCoorFailed); /* check if malloc() failed */
98 temp_val = wind_width / (float64) to_width;
99 for (u = 0; u < to_width; u++) /* calculate the x coordinate lookup table */
100 x_coor[u] = ((uint16) ((float64) u * temp_val) + from_x0);
101
102 /* allocate room for the array of pointers */
103 y_coor = (uint8 **) HDmalloc((int32) ((size_t)to_height * sizeof(uint8 *)));
104 EXCHECK(y_coor == NULL, YCoorFailed); /* check if malloc() failed */
105 temp_val = wind_height / (float64) to_height;
106 for (u = 0; u < to_height; u++) /* calculate the y coordinates */
107 y_coor[u] = from_buffer + ((uint32) ((float64) u * temp_val) + (uint32)from_y0) * (uint32)from_width;
108
109 last_buf = to_buffer; /* set the previous line pointer */
110 buf_off = to_buffer; /* set the pointer to the "to" image */
111 last_y_coor = NULL; /* force to calculate the first line */
112
113 for (u = 0; u < to_height; u++)
114 { /* go through each magnified line */
115 /* if this line is not the same as the previous one, then make it again */
116 if (y_coor[u] != last_y_coor)
117 {
118 last_y_coor = y_off = y_coor[u];
119 x_coor_temp = x_coor; /* assign the temporary pointer */
120 last_buf = buf_off; /* set the pointer to the previous line */
121 for (v = 0; v < to_width; v++) /* go through each line magnifying it */
122 *buf_off++ = y_off[*x_coor_temp++];
123 } /* end if */
124 /* this line is the same as the previous one, just copy it */
125 else
126 {
127 HDmemcpy(buf_off, last_buf, to_width); /* copy the previous line */
128 buf_off += to_width; /* advance the buffer offset pointer */
129 } /* end else */
130 } /* end for */
131 HDfree((char *) y_coor);
132 HDfree((char *) x_coor);
133 return (TRUE);
134
135 YCoorFailed: /* Failed to allocate memory for the Y coor. lookup table */
136 HDfree((VOIDP) x_coor);
137 XCoorFailed: /* Failed to allocate memory for the X coor. lookup table */
138 return (FALSE);
139 } /* end magnify() */
140
141 /**********************************************************************
142 * Function : convert8to24
143 * Purpose : Convert an 8-bit image to a 24-bit image, using the
144 * palette components already set up.
145 * Parameters :
146 * img_8_buf - pointer to the buffer which contains the 8-bit image
147 * img24_buf - pointer to the buffer in which to place the
148 * 24-bit image
149 * img_xdim, img_ydim - the width and height of the images
150 * Returns : (TRUE) for success, (FALSE) for error
151 * Calls :
152 * Called by :
153 **********************************************************************/
154 static intn
convert8to24(uint8 * img8_buf,uint8 * img24_buf,int32 img_xdim,int32 img_ydim)155 convert8to24(uint8 *img8_buf, uint8 *img24_buf, int32 img_xdim,
156 int32 img_ydim)
157 {
158 uint32 pixels; /* local counting variable */
159
160 if (img_xdim <= 0 || img_ydim <= 0) /* check for bad image dimensions */
161 return (FALSE);
162 if (img8_buf == NULL || img24_buf == NULL) /* check for invalid images */
163 return (FALSE);
164
165 pixels = (uint32)(img_xdim * img_ydim); /* get the number of pixels to process */
166 while (pixels > 0)
167 { /* do all the pixels */
168 *img24_buf++ = red_comp[*img8_buf];
169 *img24_buf++ = green_comp[*img8_buf];
170 *img24_buf++ = blue_comp[*img8_buf];
171 img8_buf++;
172 pixels--;
173 } /* end while */
174 return (TRUE);
175 } /* end convert8to24() */
176
177 static VOID
usage(void)178 usage(void)
179 {
180 printf("USAGE: make24 [-s<scale>] [-j] <input HDF file> <output HDF file>\n");
181 printf(" -s<scale> : set scale for magnifying the 8-bit input file.\n");
182 printf(" scales between 0 and 1 shrink the image, scales\n");
183 printf(" greater than 1 expand the image. Defaults to 1\n");
184 printf(" -j[quality] : use JPEG compression to store the 24-bit image\n");
185 printf(" Defaults to no compression, or quality level\n");
186 printf(" 75, if no quality is specified\n");
187 printf(" <input HDF file> : HDF file which contains an 8-bit image\n");
188 printf(" <output HDF file> : HDF file to store the 24-bit image\n");
189 exit(1);
190 } /* end usage() */
191
192 int
main(int argc,char * argv[])193 main(int argc, char *argv[])
194 {
195 intn do_jpeg = FALSE; /* flag to indicate JPEG compression */
196 intn jpeg_qual = 75; /* JPEG quality factor */
197 intn do_scale = FALSE; /* flag to indicate whether to scale images */
198 float32 img_scale = (float32) 1.0; /* scaling factor */
199 int32 xdim, ydim; /* dimensions of the image to convert */
200 intn ispal; /* whether there's a palette with the image */
201 uint8 *img_buf; /* buffer to store the image in */
202 uint8 *img24_buf; /* buffer to store the 24-bit image in */
203 uint8 *pal_buf = NULL; /* buffer to store the palette in */
204 intn file = 1; /* the arguement the files start at */
205 intn i; /* local counting variable */
206
207 if (argc < 3)
208 usage();
209
210 if (argv[1][0] == '-' || argv[1][0] == '/')
211 { /* check command line */
212 if ((argv[1][1] != 's' && argv[1][1] != 'j') || argc < 4)
213 usage();
214
215 while (argv[file][0] == '-' || argv[file][0] == '/')
216 {
217 switch (argv[file][1])
218 {
219 case 's':
220 if ((img_scale = (float32) atof(&argv[file][2])) <= (float32)0.0)
221 { /* check for valid scale */
222 printf("Bad scale, must be greater than 0\n");
223 return (1);
224 } /* end if */
225 do_scale = TRUE;
226 break;
227
228 case 'j':
229 if ((jpeg_qual = atoi(&argv[file][2])) <= 0 || jpeg_qual > 100)
230 {
231 printf("Bad JPEG quality setting, should be between\n");
232 printf("1 and 100, using default value of 75\n");
233 jpeg_qual = 75;
234 } /* end if */
235 do_jpeg = TRUE;
236 break;
237
238 default:
239 usage();
240
241 } /* end switch */
242 file++;
243 } /* end while */
244 } /* end if */
245
246 /* get the image dimensions */
247 if (DFR8getdims(argv[file], &xdim, &ydim, &ispal) == FAIL)
248 {
249 printf("Error, bad dimensions in file: %s\n", argv[file]);
250 HEprint(stdout, 0);
251 return (1);
252 } /* end if */
253
254 if ((img_buf = (uint8 *) HDmalloc((size_t)(xdim * ydim))) == NULL)
255 {
256 printf("Error, cannot allocate space for %dx%d image\n", (int)xdim, (int)ydim);
257 return (1);
258 } /* end if */
259
260 if (ispal)
261 {
262 if ((pal_buf = (uint8 *) HDmalloc(768)) == NULL)
263 {
264 printf("Error, cannot allocate space for image palette\n");
265 return (1);
266 } /* end if */
267 } /* end if */
268 else
269 printf("No palette associated with image, using default grey scale converion\n");
270
271 if (DFR8getimage(argv[file], img_buf, xdim, ydim, (ispal ? pal_buf : NULL)) == FAIL)
272 {
273 printf("Error reading image\n");
274 HEprint(stdout, 0);
275 return (1);
276 } /* end if */
277
278 if (do_scale)
279 { /* check whether we should scale the image */
280 uint8 *scaled_image; /* storage for the scaled image */
281 int32 new_xdim, new_ydim; /* the new image's x and y dim. */
282
283 new_xdim = (int32) (img_scale * (float32)xdim); /* calc. new image's dimensions */
284 new_ydim = (int32) (img_scale * (float32)ydim);
285 if ((scaled_image = (uint8 *) HDmalloc((size_t)(new_xdim * new_ydim))) == NULL)
286 {
287 printf("Error, cannot allocate space for %dx%d scaled image\n", (int)new_xdim, (int)new_ydim);
288 return (1);
289 } /* end if */
290 if (!magnify(img_buf, scaled_image, 0, 0, xdim - 1, ydim - 1, xdim, ydim, new_xdim, new_ydim))
291 {
292 printf("Error scaling image, out of memory or bad dimensions\n");
293 return (1);
294 } /* end if */
295 HDfree((VOIDP) img_buf); /* free the old image */
296
297 img_buf = scaled_image; /* use the new image for further processing */
298 xdim = new_xdim;
299 ydim = new_ydim;
300 } /* end if */
301
302 /* Generate the RGB components for the 8 -> 24 bit converter */
303 if (ispal)
304 {
305 uint8 *pal_ptr = pal_buf; /* temporary pointer into the palette */
306
307 for (i = 0; i < 256; i++)
308 {
309 red_comp[i] = *pal_ptr++;
310 green_comp[i] = *pal_ptr++;
311 blue_comp[i] = *pal_ptr++;
312 } /* end for */
313 } /* end if */
314 else
315 { /* no palette, use a greyscale palette */
316 for (i = 0; i < 256; i++)
317 red_comp[i] = green_comp[i] = blue_comp[i] = (uint8) i;
318 } /* end else */
319
320 /* allocate space for the 24-bit image */
321 if ((img24_buf = (uint8 *) HDmalloc((size_t)(xdim * ydim * 3))) == NULL)
322 {
323 printf("Error, cannot allocate space for %dx%d 24-bit image\n", (int)xdim, (int)ydim);
324 return (1);
325 } /* end if */
326
327 /* convert the image */
328 if (!convert8to24(img_buf, img24_buf, xdim, ydim))
329 {
330 printf("Error converting 8-bit image to 24-bit image\n");
331 return (1);
332 } /* end if */
333
334 if (do_jpeg)
335 { /* set up JPEG compression if necessary */
336 cinfo.jpeg.quality = jpeg_qual; /* set JPEG comp. parameters */
337 cinfo.jpeg.force_baseline = TRUE;
338 DF24setcompress(COMP_JPEG, &cinfo); /* set compression parameters */
339 } /* end if */
340
341 /* store 24-bit image */
342 if (DF24putimage(argv[file + 1], (VOIDP) img24_buf, xdim, ydim) == FAIL)
343 {
344 printf("Error storing 24-bit image\n");
345 HEprint(stdout, 0);
346 return (1);
347 } /* end if */
348
349 return (0);
350 } /* end make24 */
351