[4] | 1 | /****************************************************************************** |
---|
| 2 | * SAGE - Scalable Adaptive Graphics Environment |
---|
| 3 | * |
---|
| 4 | * Copyright (C) 2004 Electronic Visualization Laboratory, |
---|
| 5 | * University of Illinois at Chicago |
---|
| 6 | * |
---|
| 7 | * All rights reserved. |
---|
| 8 | * |
---|
| 9 | * Redistribution and use in source and binary forms, with or without |
---|
| 10 | * modification, are permitted provided that the following conditions are met: |
---|
| 11 | * |
---|
| 12 | * * Redistributions of source code must retain the above copyright |
---|
| 13 | * notice, this list of conditions and the following disclaimer. |
---|
| 14 | * * Redistributions in binary form must reproduce the above |
---|
| 15 | * copyright notice, this list of conditions and the following disclaimer |
---|
| 16 | * in the documentation and/or other materials provided with the distribution. |
---|
| 17 | * * Neither the name of the University of Illinois at Chicago nor |
---|
| 18 | * the names of its contributors may be used to endorse or promote |
---|
| 19 | * products derived from this software without specific prior written permission. |
---|
| 20 | * |
---|
| 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
---|
| 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
---|
| 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
---|
| 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
---|
| 25 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
---|
| 26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
---|
| 27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
---|
| 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
---|
| 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
---|
| 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
---|
| 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
| 32 | * |
---|
| 33 | * Direct questions, comments etc about SAGE to http://www.evl.uic.edu/cavern/forum/ |
---|
| 34 | * |
---|
| 35 | *****************************************************************************/ |
---|
| 36 | |
---|
| 37 | #ifndef lint |
---|
| 38 | static char sccsid[] = "@(#)sgigt.c 1.8 4/25/89"; |
---|
| 39 | #endif |
---|
| 40 | |
---|
| 41 | #include <stdio.h> |
---|
| 42 | #include <gl.h> |
---|
| 43 | #include <gl/device.h> |
---|
| 44 | #include "tiffio.h" |
---|
| 45 | #include "imginfo.h" |
---|
| 46 | |
---|
| 47 | static u_long *raster; /* displayable image */ |
---|
| 48 | static u_short bitspersample; |
---|
| 49 | static u_short samplesperpixel; |
---|
| 50 | static u_short photometric; |
---|
| 51 | static u_short orientation; |
---|
| 52 | static u_short *redcmap, *greencmap, *bluecmap;/* colormap for palette images */ |
---|
| 53 | |
---|
| 54 | #define rgba(r, g, b, a) ((a)<<24 | (b)<<16 | (g)<<8 | (r)) |
---|
| 55 | #define rgbi(r, g, b) (0xFF000000 | (b)<<16 | (g)<<8 | (r)) |
---|
| 56 | |
---|
| 57 | IMG * |
---|
| 58 | TIFFmakedisp(fname) |
---|
| 59 | char *fname; |
---|
| 60 | { |
---|
| 61 | TIFF *tif; |
---|
| 62 | short width, height; |
---|
| 63 | register IMG *im; |
---|
| 64 | |
---|
| 65 | tif = TIFFOpen(fname, "r"); |
---|
| 66 | if(tif == NULL) |
---|
| 67 | return NULL; |
---|
| 68 | |
---|
| 69 | TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); |
---|
| 70 | TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); |
---|
| 71 | im = (IMG *)malloc(sizeof(IMG)); |
---|
| 72 | im->type = IT_LONG; |
---|
| 73 | im->rowbytes = sizeof(long) * width; |
---|
| 74 | im->xsize = width; |
---|
| 75 | im->ysize = height; |
---|
| 76 | im->data = (unsigned char *)malloc(im->rowbytes * height); |
---|
| 77 | if(im->data == NULL) { |
---|
| 78 | fprintf(stderr, "Can't malloc %d bytes of memory for image\n", |
---|
| 79 | im->rowbytes * height); |
---|
| 80 | exit(2); |
---|
| 81 | } |
---|
| 82 | if(tiffgt(tif, width, height, (u_long *)im->data) == 0) { |
---|
| 83 | free(im->data); |
---|
| 84 | free(im); |
---|
| 85 | im = NULL; |
---|
| 86 | } |
---|
| 87 | TIFFClose(tif); |
---|
| 88 | return im; |
---|
| 89 | } |
---|
| 90 | |
---|
| 91 | RGBvalue **BWmap; |
---|
| 92 | |
---|
| 93 | static |
---|
| 94 | tiffgt(tif, w, h, raster) |
---|
| 95 | TIFF *tif; |
---|
| 96 | int w, h; |
---|
| 97 | u_long *raster; |
---|
| 98 | { |
---|
| 99 | u_short minsamplevalue, maxsamplevalue, planarconfig; |
---|
| 100 | RGBvalue *Map; |
---|
| 101 | int e; |
---|
| 102 | |
---|
| 103 | if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { |
---|
| 104 | switch (samplesperpixel) { |
---|
| 105 | case 1: |
---|
| 106 | photometric = PHOTOMETRIC_MINISBLACK; |
---|
| 107 | break; |
---|
| 108 | case 3: case 4: |
---|
| 109 | photometric = PHOTOMETRIC_RGB; |
---|
| 110 | break; |
---|
| 111 | default: |
---|
| 112 | fprintf(stderr, "Missing needed \"%s\" tag.\n", |
---|
| 113 | "PhotometricInterpretation"); |
---|
| 114 | return (0); |
---|
| 115 | } |
---|
| 116 | printf("No \"PhotometricInterpretation\" tag, assuming %s.\n", |
---|
| 117 | photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black"); |
---|
| 118 | } |
---|
| 119 | if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel)) |
---|
| 120 | samplesperpixel = 1; |
---|
| 121 | if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample)) |
---|
| 122 | bitspersample = 8; |
---|
| 123 | if (!TIFFGetField(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue)) |
---|
| 124 | minsamplevalue = 0; |
---|
| 125 | if (!TIFFGetField(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue)) |
---|
| 126 | maxsamplevalue = (1<<bitspersample)-1; |
---|
| 127 | Map = NULL; |
---|
| 128 | switch (photometric) { |
---|
| 129 | case PHOTOMETRIC_RGB: |
---|
| 130 | case PHOTOMETRIC_MINISBLACK: |
---|
| 131 | if (minsamplevalue == 0 && maxsamplevalue == 255) |
---|
| 132 | break; |
---|
| 133 | /* fall thru... */ |
---|
| 134 | case PHOTOMETRIC_MINISWHITE: { |
---|
| 135 | register int x, range; |
---|
| 136 | |
---|
| 137 | range = maxsamplevalue - minsamplevalue + 1; |
---|
| 138 | Map = (RGBvalue *)malloc(range * sizeof (RGBvalue)); |
---|
| 139 | if (Map == NULL) { |
---|
| 140 | fprintf(stderr, |
---|
| 141 | "No space for photometric conversion table.\n"); |
---|
| 142 | return (0); |
---|
| 143 | } |
---|
| 144 | if (photometric == PHOTOMETRIC_MINISWHITE) { |
---|
| 145 | for (x = 0; x < range; x++) |
---|
| 146 | Map[x] = ((range - x) * 255) / range; |
---|
| 147 | } else { |
---|
| 148 | for (x = 0; x < range; x++) |
---|
| 149 | Map[x] = (x * 255) / range; |
---|
| 150 | } |
---|
| 151 | if (bitspersample < 8 && photometric != PHOTOMETRIC_RGB) { |
---|
| 152 | if (!makebwmap(Map)) |
---|
| 153 | return (0); |
---|
| 154 | /* no longer need Map, free it */ |
---|
| 155 | free((char *)Map); |
---|
| 156 | Map = NULL; |
---|
| 157 | } |
---|
| 158 | break; |
---|
| 159 | } |
---|
| 160 | case PHOTOMETRIC_PALETTE: |
---|
| 161 | if (!TIFFGetField(tif, TIFFTAG_COLORMAP, |
---|
| 162 | &redcmap, &greencmap, &bluecmap)) { |
---|
| 163 | fprintf(stderr, "Missing required \"Colormap\" tag.\n"); |
---|
| 164 | return (0); |
---|
| 165 | } |
---|
| 166 | break; |
---|
| 167 | } |
---|
| 168 | TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig); |
---|
| 169 | if (planarconfig == PLANARCONFIG_SEPARATE) |
---|
| 170 | e = gtseparate(tif, raster, Map, h, w); |
---|
| 171 | else |
---|
| 172 | e = gtcontig(tif, raster, Map, h, w); |
---|
| 173 | if (Map) |
---|
| 174 | free((char *)Map); |
---|
| 175 | return (e); |
---|
| 176 | } |
---|
| 177 | |
---|
| 178 | setorientation(tif, h) |
---|
| 179 | TIFF *tif; |
---|
| 180 | int h; |
---|
| 181 | { |
---|
| 182 | int y; |
---|
| 183 | |
---|
| 184 | if (!TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation)) |
---|
| 185 | orientation = ORIENTATION_TOPLEFT; |
---|
| 186 | switch (orientation) { |
---|
| 187 | case ORIENTATION_BOTRIGHT: |
---|
| 188 | case ORIENTATION_RIGHTBOT: /* XXX */ |
---|
| 189 | case ORIENTATION_LEFTBOT: /* XXX */ |
---|
| 190 | printf("Warning, using bottom-left orientation.\n"); |
---|
| 191 | orientation = ORIENTATION_BOTLEFT; |
---|
| 192 | /* fall thru... */ |
---|
| 193 | case ORIENTATION_BOTLEFT: |
---|
| 194 | y = 0; |
---|
| 195 | break; |
---|
| 196 | case ORIENTATION_TOPRIGHT: |
---|
| 197 | case ORIENTATION_RIGHTTOP: /* XXX */ |
---|
| 198 | case ORIENTATION_LEFTTOP: /* XXX */ |
---|
| 199 | printf("Warning, using top-left orientation.\n"); |
---|
| 200 | orientation = ORIENTATION_TOPLEFT; |
---|
| 201 | /* fall thru... */ |
---|
| 202 | case ORIENTATION_TOPLEFT: |
---|
| 203 | y = h-1; |
---|
| 204 | break; |
---|
| 205 | } |
---|
| 206 | return (y); |
---|
| 207 | } |
---|
| 208 | |
---|
| 209 | gtcontig(tif, raster, Map, h, w) |
---|
| 210 | TIFF *tif; |
---|
| 211 | u_long *raster; |
---|
| 212 | register RGBvalue *Map; |
---|
| 213 | int h, w; |
---|
| 214 | { |
---|
| 215 | register u_char *pp; |
---|
| 216 | register u_long *cp; |
---|
| 217 | register int x; |
---|
| 218 | int scanline, row, y; |
---|
| 219 | u_char *buf; |
---|
| 220 | |
---|
| 221 | buf = (u_char *)malloc(TIFFScanlineSize(tif)); |
---|
| 222 | if (buf == 0) { |
---|
| 223 | fprintf(stderr, "No space for scanline buffer\n"); |
---|
| 224 | return (0); |
---|
| 225 | } |
---|
| 226 | y = setorientation(tif, h); |
---|
| 227 | for (row = 0; row < h; row++) { |
---|
| 228 | if (TIFFReadScanline(tif, buf, row, 0) < 0) |
---|
| 229 | break; |
---|
| 230 | pp = buf; |
---|
| 231 | cp = raster + y*w; |
---|
| 232 | switch (photometric) { |
---|
| 233 | case PHOTOMETRIC_RGB: |
---|
| 234 | rgb: |
---|
| 235 | switch (bitspersample) { |
---|
| 236 | case 8: |
---|
| 237 | if (Map) { |
---|
| 238 | for (x = w; x-- > 0;) { |
---|
| 239 | pp[0] = Map[pp[0]]; |
---|
| 240 | pp[1] = Map[pp[1]]; |
---|
| 241 | pp[2] = Map[pp[2]]; |
---|
| 242 | pp += samplesperpixel; |
---|
| 243 | } |
---|
| 244 | pp = buf; |
---|
| 245 | } |
---|
| 246 | if(samplesperpixel == 4) { |
---|
| 247 | for(x = w; --x >= 0; pp += 4) |
---|
| 248 | *cp++ = rgba(pp[0], pp[1], pp[2],pp[3]); |
---|
| 249 | } else { |
---|
| 250 | for (x = w; x-- > 0; pp += samplesperpixel) |
---|
| 251 | *cp++ = rgbi(pp[0], pp[1], pp[2]); |
---|
| 252 | } |
---|
| 253 | break; |
---|
| 254 | case 16: { |
---|
| 255 | register u_short *wp; |
---|
| 256 | |
---|
| 257 | if (Map) { |
---|
| 258 | wp = (u_short *)pp; |
---|
| 259 | for (x = w; x-- > 0;) { |
---|
| 260 | wp[0] = Map[wp[0]]; |
---|
| 261 | wp[1] = Map[wp[1]]; |
---|
| 262 | wp[2] = Map[wp[2]]; |
---|
| 263 | wp += samplesperpixel; |
---|
| 264 | } |
---|
| 265 | } |
---|
| 266 | wp = (u_short *)pp; |
---|
| 267 | for (x = w; x-- > 0;) { |
---|
| 268 | *cp++ = rgbi(wp[0], wp[1], wp[2]); |
---|
| 269 | wp += samplesperpixel; |
---|
| 270 | } |
---|
| 271 | break; |
---|
| 272 | } |
---|
| 273 | } |
---|
| 274 | break; |
---|
| 275 | case PHOTOMETRIC_PALETTE: |
---|
| 276 | for (x = w; x-- > 0;) { |
---|
| 277 | RGBvalue c = *pp++; |
---|
| 278 | *cp++ = rgbi(redcmap[c], |
---|
| 279 | greencmap[c], bluecmap[c]); |
---|
| 280 | } |
---|
| 281 | break; |
---|
| 282 | case PHOTOMETRIC_MINISWHITE: |
---|
| 283 | case PHOTOMETRIC_MINISBLACK: |
---|
| 284 | if(samplesperpixel > 1) |
---|
| 285 | goto rgb; |
---|
| 286 | |
---|
| 287 | if (bitspersample == 8) { |
---|
| 288 | register RGBvalue c; |
---|
| 289 | |
---|
| 290 | for (x = w; x-- > 0;) { |
---|
| 291 | c = Map[*pp++]; |
---|
| 292 | *cp++ = rgbi(c, c, c); |
---|
| 293 | } |
---|
| 294 | } else |
---|
| 295 | gtbw(bitspersample, w, cp, pp); |
---|
| 296 | break; |
---|
| 297 | } |
---|
| 298 | y += (orientation == ORIENTATION_TOPLEFT ? -1 : 1); |
---|
| 299 | } |
---|
| 300 | return (1); |
---|
| 301 | } |
---|
| 302 | |
---|
| 303 | gtseparate(tif, raster, Map, h, w) |
---|
| 304 | TIFF *tif; |
---|
| 305 | u_long *raster; |
---|
| 306 | register RGBvalue *Map; |
---|
| 307 | int h, w; |
---|
| 308 | { |
---|
| 309 | register u_long *cp; |
---|
| 310 | register int x; |
---|
| 311 | u_char *red; |
---|
| 312 | int scanline, row, y; |
---|
| 313 | |
---|
| 314 | scanline = TIFFScanlineSize(tif); |
---|
| 315 | switch (samplesperpixel) { |
---|
| 316 | case 1: |
---|
| 317 | red = (u_char *)malloc(scanline); |
---|
| 318 | break; |
---|
| 319 | case 3: case 4: |
---|
| 320 | red = (u_char *)malloc(4*scanline); |
---|
| 321 | break; |
---|
| 322 | } |
---|
| 323 | y = setorientation(tif, h); |
---|
| 324 | for (row = 0; row < h; row++) { |
---|
| 325 | cp = raster + y*w; |
---|
| 326 | if (TIFFReadScanline(tif, red, row, 0) < 0) |
---|
| 327 | break; |
---|
| 328 | switch (photometric) { |
---|
| 329 | case PHOTOMETRIC_RGB: { |
---|
| 330 | register u_char *r, *g, *b, *a; |
---|
| 331 | |
---|
| 332 | r = red; |
---|
| 333 | if (TIFFReadScanline(tif, g = r + scanline, row, 1) < 0) |
---|
| 334 | break; |
---|
| 335 | if (TIFFReadScanline(tif, b = g + scanline, row, 2) < 0) |
---|
| 336 | break; |
---|
| 337 | if(samplesperpixel == 4) { |
---|
| 338 | a = b + scanline; |
---|
| 339 | if(TIFFReadScanline(tif, a, row, 3) < 0) |
---|
| 340 | break; |
---|
| 341 | } |
---|
| 342 | switch (bitspersample) { |
---|
| 343 | case 8: |
---|
| 344 | if(samplesperpixel == 4) { |
---|
| 345 | for(x = w; --x >= 0; ) |
---|
| 346 | *cp++ = rgba(*r++, *g++, *b++, *a++); |
---|
| 347 | } else { |
---|
| 348 | for (x = w; x-- > 0;) |
---|
| 349 | *cp++ = rgbi(*r++, *g++, *b++); |
---|
| 350 | } |
---|
| 351 | break; |
---|
| 352 | case 16: |
---|
| 353 | #define wp(x) ((u_short *)(x)) |
---|
| 354 | for (x = 0; x < w; x++) |
---|
| 355 | *cp++ = rgbi( |
---|
| 356 | Map[wp(r)[x]], |
---|
| 357 | Map[wp(g)[x]], |
---|
| 358 | Map[wp(b)[x]]); |
---|
| 359 | break; |
---|
| 360 | #undef wp |
---|
| 361 | } |
---|
| 362 | break; |
---|
| 363 | } |
---|
| 364 | case PHOTOMETRIC_PALETTE: { |
---|
| 365 | register u_char *pp = red; |
---|
| 366 | for (x = w; x-- > 0;) { |
---|
| 367 | RGBvalue c = *pp++; |
---|
| 368 | *cp++ = rgbi(redcmap[c], |
---|
| 369 | greencmap[c], bluecmap[c]); |
---|
| 370 | } |
---|
| 371 | break; |
---|
| 372 | } |
---|
| 373 | case PHOTOMETRIC_MINISWHITE: |
---|
| 374 | case PHOTOMETRIC_MINISBLACK: |
---|
| 375 | if (bitspersample == 8) { |
---|
| 376 | register u_short *pp = (u_short *)red; |
---|
| 377 | register RGBvalue c; |
---|
| 378 | |
---|
| 379 | for (x = w; x-- > 0;) { |
---|
| 380 | c = Map[*pp++]; |
---|
| 381 | *cp++ = rgbi(c, c, c); |
---|
| 382 | } |
---|
| 383 | } else |
---|
| 384 | gtbw(bitspersample, w, Map, cp, red); |
---|
| 385 | break; |
---|
| 386 | } |
---|
| 387 | y += (orientation == ORIENTATION_TOPLEFT ? -1 : 1); |
---|
| 388 | } |
---|
| 389 | if (red) |
---|
| 390 | free(red); |
---|
| 391 | return (1); |
---|
| 392 | } |
---|
| 393 | |
---|
| 394 | /* |
---|
| 395 | * Greyscale images with less than 8 bits/sample are handled |
---|
| 396 | * with a table to avoid lots of shits and masks. The table |
---|
| 397 | * is setup so that gtbw (below) can retrieve 8/bitspersample |
---|
| 398 | * pixel values simply by indexing into the table with one |
---|
| 399 | * number. |
---|
| 400 | */ |
---|
| 401 | makebwmap(Map) |
---|
| 402 | RGBvalue *Map; |
---|
| 403 | { |
---|
| 404 | register int i; |
---|
| 405 | int nsamples = 8 / bitspersample; |
---|
| 406 | register RGBvalue *p; |
---|
| 407 | |
---|
| 408 | BWmap = (RGBvalue **)malloc( |
---|
| 409 | 256*sizeof (RGBvalue *)+(256*nsamples*sizeof(RGBvalue))); |
---|
| 410 | if (BWmap == NULL) { |
---|
| 411 | fprintf(stderr, "No space for B&W mapping table.\n"); |
---|
| 412 | return (0); |
---|
| 413 | } |
---|
| 414 | p = (RGBvalue *)(BWmap + 256); |
---|
| 415 | for (i = 0; i < 256; i++) { |
---|
| 416 | BWmap[i] = p; |
---|
| 417 | switch (bitspersample) { |
---|
| 418 | case 1: |
---|
| 419 | *p++ = Map[i>>7]; |
---|
| 420 | *p++ = Map[(i>>6)&1]; |
---|
| 421 | *p++ = Map[(i>>5)&1]; |
---|
| 422 | *p++ = Map[(i>>4)&1]; |
---|
| 423 | *p++ = Map[(i>>3)&1]; |
---|
| 424 | *p++ = Map[(i>>2)&1]; |
---|
| 425 | *p++ = Map[(i>>1)&1]; |
---|
| 426 | *p++ = Map[i&1]; |
---|
| 427 | break; |
---|
| 428 | case 2: |
---|
| 429 | *p++ = Map[i>>6]; |
---|
| 430 | *p++ = Map[(i>>4)&3]; |
---|
| 431 | *p++ = Map[(i>>2)&3]; |
---|
| 432 | *p++ = Map[i&3]; |
---|
| 433 | break; |
---|
| 434 | case 4: |
---|
| 435 | *p++ = Map[i>>4]; |
---|
| 436 | *p++ = Map[i&0xf]; |
---|
| 437 | break; |
---|
| 438 | } |
---|
| 439 | } |
---|
| 440 | return (1); |
---|
| 441 | } |
---|
| 442 | |
---|
| 443 | #define REPEAT8(op) REPEAT4(op); REPEAT4(op) |
---|
| 444 | #define REPEAT4(op) REPEAT2(op); REPEAT2(op) |
---|
| 445 | #define REPEAT2(op) op; op |
---|
| 446 | |
---|
| 447 | gtbw(bitspersample, w, cp, pp) |
---|
| 448 | int bitspersample, w; |
---|
| 449 | register u_long *cp; |
---|
| 450 | register u_char *pp; |
---|
| 451 | { |
---|
| 452 | register RGBvalue c, *bw; |
---|
| 453 | register int x; |
---|
| 454 | |
---|
| 455 | switch (bitspersample) { |
---|
| 456 | case 1: |
---|
| 457 | for (x = w; x > 0; x -= 8) { |
---|
| 458 | bw = BWmap[*pp++]; |
---|
| 459 | REPEAT8(c = *bw++; *cp++ = rgbi(c, c, c)); |
---|
| 460 | } |
---|
| 461 | break; |
---|
| 462 | case 2: |
---|
| 463 | for (x = w; x > 0; x -= 4) { |
---|
| 464 | bw = BWmap[*pp++]; |
---|
| 465 | REPEAT4(c = *bw++; *cp++ = rgbi(c, c, c)); |
---|
| 466 | } |
---|
| 467 | break; |
---|
| 468 | case 4: |
---|
| 469 | for (x = w; x > 0; x -= 2) { |
---|
| 470 | bw = BWmap[*pp++]; |
---|
| 471 | REPEAT2(c = *bw++; *cp++ = rgbi(c, c, c)); |
---|
| 472 | } |
---|
| 473 | break; |
---|
| 474 | } |
---|
| 475 | } |
---|