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