#include "host.h"
#include "bitstrm.h"
Go to the source code of this file.
Read the header of a tif format image and prepare to read the rest.
Definition at line 197 of file imgtiff.cpp.
References __NATIVE__, BADIMAGEFORMAT, ERRCODE::error(), FALSE, INTEL, LOG, MOTO, READFAILED, reverse16(), reverse32(), tprintf(), and TRUE.
00204 { 00205 INT16 filetype; 00206 INT32 start; //start of tiff directory 00207 INT16 entries; //no of tiff entries 00208 INT32 imagestart; //location of image in file 00209 INT32 resoffset; //location of res 00210 TIFFENTRY tiffentry; //tag table entry 00211 BOOL8 compressed; //compression control 00212 MYRATIONAL resinfo; //resolution 00213 BOOL8 strips = false; //if in strips 00214 00215 *xsize = -1; //illegal values 00216 *ysize = -1; 00217 *bpp = -1; 00218 *res = -1; 00219 resoffset = -1; 00220 if (read (fd, (char *) &filetype, sizeof filetype) != sizeof filetype 00221 || filetype != INTEL && filetype != MOTO) { 00222 BADIMAGEFORMAT.error ("read_tif_image", LOG, "Filetype"); 00223 return -1; 00224 } 00225 lseek (fd, 4L, 0); 00226 if (read (fd, (char *) &start, sizeof start) != sizeof start) { 00227 READFAILED.error ("read_tif_image", LOG, "Start of tag table"); 00228 return -1; 00229 } 00230 00231 if (filetype != __NATIVE__) 00232 start = reverse32 (start); 00233 if (start <= 0) { 00234 BADIMAGEFORMAT.error ("read_tif_image", LOG, "Start of tag table"); 00235 return -1; 00236 } 00237 lseek (fd, start, 0); 00238 if (read (fd, (char *) &entries, sizeof (INT16)) != sizeof (INT16)) { 00239 BADIMAGEFORMAT.error ("read_tif_image", LOG, "Size of tag table"); 00240 return -1; 00241 } 00242 if (filetype != __NATIVE__) 00243 entries = reverse16 (entries); 00244 // printf("No of tiff directory entries=%d\n",entries); 00245 imagestart = 0; 00246 compressed = FALSE; 00247 for (; entries-- > 0;) { 00248 if (read (fd, (char *) &tiffentry, sizeof tiffentry) != 00249 sizeof tiffentry) { 00250 BADIMAGEFORMAT.error ("read_tif_image", LOG, "Tag table entry"); 00251 return -1; 00252 } 00253 if (filetype != __NATIVE__) { 00254 tiffentry.type = reverse16 (tiffentry.type); 00255 tiffentry.tag = reverse16 (tiffentry.tag); 00256 tiffentry.length = reverse32 (tiffentry.length); 00257 } 00258 if (tiffentry.type != 3) { //Full 32bit value 00259 if (filetype != __NATIVE__) 00260 tiffentry.value = reverse32 (tiffentry.value); 00261 } 00262 else { 00263 /* A 16bit value in 4 bytes - handle with care. SEE NOTE at start of file */ 00264 if (__NATIVE__ == MOTO) { 00265 if (filetype == MOTO) //MOTO file on MOTO Machine 00266 tiffentry.value = tiffentry.value >> 16; 00267 else //INTEL file on MOTO Machine 00268 tiffentry.value = reverse32 (tiffentry.value); 00269 } 00270 else { //INTEL Machine 00271 if (filetype == MOTO) //MOTO file on INTEL Machine 00272 tiffentry.value = reverse16 ((UINT16) tiffentry.value); 00273 //INTEL file on INTEL Machine NO ACTION NEEDED 00274 } 00275 //Clear top 2 MSBytes 00276 tiffentry.value &= 0x0000ffff; 00277 } 00278 00279 // printf("Tag=%x, Type=%x, Length=%x, value=%x\n", 00280 // tiffentry.tag,tiffentry.type,tiffentry.length,tiffentry.value); 00281 switch (tiffentry.tag) { 00282 case 0x101: 00283 *ysize = tiffentry.value; 00284 break; 00285 case 0x100: 00286 *xsize = tiffentry.value; 00287 break; 00288 case 0x102: 00289 if (tiffentry.length == 1) 00290 *bpp = (INT8) tiffentry.value; 00291 else 00292 *bpp = 24; 00293 break; 00294 case 0x111: 00295 imagestart = tiffentry.value; 00296 strips = tiffentry.length > 1; 00297 break; 00298 case 0x103: 00299 if (tiffentry.value == 3) { 00300 compressed = TRUE; 00301 } 00302 else if (tiffentry.value != 1) { 00303 BADIMAGEFORMAT.error ("read_tif_image", LOG, "Compression"); 00304 return -1; 00305 } 00306 break; 00307 case 0x11a: 00308 case 0x11b: 00309 //resolution 00310 resoffset = tiffentry.value; 00311 break; 00312 case 0x106: 00313 *photo = (INT8) tiffentry.value; 00314 break; 00315 } //endswitch 00316 } 00317 if (*xsize <= 0 || *ysize <= 0 || *bpp > 24 || imagestart <= 0) { 00318 BADIMAGEFORMAT.error ("read_tif_image", LOG, "Vital tag"); 00319 return -1; 00320 } 00321 tprintf ("Image has %d bit%c per pixel and size (%d,%d)\n", 00322 *bpp, *bpp == 1 ? ' ' : 's', *xsize, *ysize); 00323 if (resoffset >= 0) { 00324 lseek (fd, resoffset, 0); 00325 if (read (fd, (char *) &resinfo, sizeof (resinfo)) != sizeof (resinfo)) { 00326 READFAILED.error ("read_tif_image", LOG, "Resolution"); 00327 return -1; 00328 } 00329 if (filetype != __NATIVE__) { 00330 resinfo.top = reverse32 (resinfo.top); 00331 resinfo.bottom = reverse32 (resinfo.bottom); 00332 } 00333 *res = resinfo.top / resinfo.bottom; 00334 tprintf ("Resolution=%d\n", *res); 00335 } 00336 lseek (fd, (long) imagestart, 0); 00337 if (strips) { 00338 if (read (fd, (char *) &imagestart, sizeof (imagestart)) != 00339 sizeof (imagestart)) { 00340 READFAILED.error ("read_tif_image", LOG, "Strip offset"); 00341 return -1; 00342 } 00343 if (filetype != __NATIVE__) 00344 imagestart = reverse32 (imagestart); 00345 //indirection 00346 lseek (fd, (long) imagestart, 0); 00347 } 00348 return compressed ? -2 : 0; 00349 }
INT32 read_eol | ( | R_BITSTREAM * | bits, | |
UINT16 & | code | |||
) |
Take bits out of the stream until and end-of-line code is hit.
Definition at line 436 of file imgtiff.cpp.
References EOL_CODE, EOL_LENGTH, EOL_MASK, FALSE, R_BITSTREAM::read_code(), and TRUE.
Referenced by read_tif_image().
00439 { 00440 BOOL8 anyones; //any 1 bits skipped 00441 INT32 bitcount; //total bits skipped 00442 00443 anyones = FALSE; 00444 bitcount = 0; 00445 while ((code & EOL_MASK) != EOL_CODE) { 00446 if (code & 1) 00447 anyones = TRUE; //discarded one bit 00448 bitcount++; //total discarded bits 00449 code = bits->read_code (1); //take single bits 00450 } 00451 //extract EOL code 00452 code = bits->read_code (EOL_LENGTH); 00453 00454 if (!anyones) 00455 bitcount = 0; //ignore filler bits 00456 return bitcount; 00457 }
Read a whole tif image into memory.
Definition at line 355 of file imgtiff.cpp.
References IMAGE::capture(), IMAGELINE::init(), long_black_codes, long_black_lengths, LONG_CODE_SIZE, long_white_codes, long_white_lengths, R_BITSTREAM::masks(), R_BITSTREAM::open(), IMAGELINE::pixels, IMAGE::put_line(), R_BITSTREAM::read_code(), read_eol(), short_black_codes, short_black_lengths, SHORT_CODE_SIZE, short_white_codes, short_white_lengths, tprintf(), and TRUE.
00362 { 00363 INT32 xindex; //indices in image 00364 INT32 yindex; 00365 INT32 length; //short length 00366 INT32 biglength; //extender 00367 UINT8 *lengths; //current lengths 00368 UINT16 *codes; //current codes 00369 UINT16 codeword; //current code word 00370 IMAGELINE imageline; //current line 00371 IMAGE image; //dummy image 00372 R_BITSTREAM bits; //read bitstream 00373 UINT8 colour; //current colour 00374 00375 image.capture (pixels, xsize, ysize, bpp); 00376 codeword = bits.open (fd); //open bitstream 00377 read_eol(&bits, codeword); //find end of line 00378 for (yindex = ysize - 1; yindex >= 0; yindex--) { 00379 imageline.init (); 00380 colour = TRUE; 00381 for (xindex = 0; xindex < xsize;) { 00382 if (colour) { 00383 lengths = long_white_lengths; 00384 codes = long_white_codes; 00385 } 00386 else { 00387 lengths = long_black_lengths; 00388 codes = long_black_codes; 00389 } 00390 for (biglength = 0; biglength < LONG_CODE_SIZE 00391 && (codeword & bits.masks (*lengths)) 00392 != *codes; codes++, lengths++, biglength++); 00393 if (biglength < LONG_CODE_SIZE) { 00394 codeword = bits.read_code (*lengths); 00395 biglength++; 00396 biglength *= SHORT_CODE_SIZE; 00397 } 00398 else 00399 biglength = 0; 00400 if (colour) { 00401 lengths = short_white_lengths; 00402 codes = short_white_codes; 00403 } 00404 else { 00405 lengths = short_black_lengths; 00406 codes = short_black_codes; 00407 } 00408 for (length = 0; length < SHORT_CODE_SIZE 00409 && (codeword & bits.masks (*lengths)) 00410 != *codes; codes++, lengths++, length++); 00411 if (length < SHORT_CODE_SIZE) { 00412 codeword = bits.read_code (*lengths); 00413 for (length += biglength; length > 0; length--, xindex++) 00414 imageline.pixels[xindex] = colour; 00415 colour = !colour; 00416 } 00417 else 00418 break; 00419 } 00420 if (xindex < xsize) { 00421 tprintf ("%d pixels short on line %d", xsize - xindex, yindex); 00422 tprintf (", unknown code=%x\n", codeword); 00423 } 00424 xindex = read_eol (&bits, codeword); 00425 if (xindex > 0) 00426 tprintf ("Discarding %d bits on line %d\n", xindex, yindex); 00427 image.put_line (0, yindex, xsize, &imageline, 0); 00428 } 00429 return 0; 00430 }
INT8 write_intel_tif | ( | int | fd, | |
UINT8 * | pixels, | |||
INT32 | xsize, | |||
INT32 | ysize, | |||
INT8 | bpp, | |||
INT8 | photo, | |||
INT32 | res | |||
) |
Write a whole tif format image and close the file.
Definition at line 480 of file imgtiff.cpp.
References INTEL, and write_tif_image().
00488 { 00489 return write_tif_image (fd, pixels, xsize, ysize, bpp, res, INTEL, photo); 00490 //use intel format 00491 }
INT8 write_inverse_tif | ( | int | fd, | |
UINT8 * | pixels, | |||
INT32 | xsize, | |||
INT32 | ysize, | |||
INT8 | bpp, | |||
INT8 | photo, | |||
INT32 | res | |||
) |
Write a whole tif format image and close the file.
Definition at line 497 of file imgtiff.cpp.
References INTEL, and write_tif_image().
00505 { 00506 return write_tif_image (fd, pixels, xsize, ysize, bpp, res, INTEL, 00507 1 - photo); 00508 //use intel format 00509 }
INT8 write_moto_tif | ( | int | fd, | |
UINT8 * | pixels, | |||
INT32 | xsize, | |||
INT32 | ysize, | |||
INT8 | bpp, | |||
INT8 | photo, | |||
INT32 | res | |||
) |
Write a whole tif format image and close the file.
Definition at line 463 of file imgtiff.cpp.
References MOTO, and write_tif_image().
00471 { 00472 return write_tif_image (fd, pixels, xsize, ysize, bpp, res, MOTO, photo); 00473 //use moto format 00474 }
INT8 write_tif_image | ( | int | fd, | |
UINT8 * | pixels, | |||
INT32 | xsize, | |||
INT32 | ysize, | |||
INT8 | bpp, | |||
INT32 | res, | |||
INT16 | type, | |||
INT16 | photo | |||
) |
Write a whole tif format image and close the file.
Definition at line 515 of file imgtiff.cpp.
References __NATIVE__, COMPUTE_IMAGE_XDIM, ENTRIES, ERRCODE::error(), INTEL, TIFFENTRY::length, LOG, MOTO, resolution, reverse16(), reverse32(), START, TIFFENTRY::tag, TIFFENTRY::type, TIFFENTRY::value, and WRITEFAILED.
Referenced by write_intel_tif(), write_inverse_tif(), and write_moto_tif().
00524 { 00525 INT32 size; //line/image size 00526 INT16 entries; //no of tiff entries 00527 INT32 start; //start of tag table 00528 INT32 zero = 0; 00529 MYRATIONAL resolution; //resolution 00530 TIFFENTRY entry; //current entry 00531 00532 static TIFFENTRY tags[ENTRIES] = { 00533 {0xfe, 4, 1, 0}, 00534 {0x100, 3, 1, 0}, 00535 {0x101, 3, 1, 0}, 00536 {0x102, 3, 1, 0}, 00537 {0x103, 3, 1, 1}, 00538 {0x106, 3, 1, 1}, 00539 { /*line art */ 00540 0x107, 3, 1, 1 00541 }, 00542 {0x10a, 3, 1, 1}, 00543 { 00544 0x111, 4, 1, START + ENTRIES * sizeof (TIFFENTRY) 00545 + sizeof (INT32) + sizeof (short) + sizeof (MYRATIONAL) * 2 00546 } 00547 , 00548 {0x112, 3, 1, 1} 00549 , 00550 {0x115, 3, 1, 1} 00551 , 00552 {0x116, 4, 1, 0} 00553 , 00554 {0x117, 4, 1, 0} 00555 , 00556 {0x118, 3, 1, 0} 00557 , 00558 {0x119, 3, 1, 1} 00559 , 00560 { 00561 0x11a, 5, 1, START + ENTRIES * sizeof (TIFFENTRY) 00562 + sizeof (INT32) + sizeof (short) 00563 }, 00564 { 00565 0x11b, 5, 1, START + ENTRIES * sizeof (TIFFENTRY) 00566 + sizeof (INT32) + sizeof (short) + sizeof (MYRATIONAL) 00567 } 00568 , 00569 {0x11c, 3, 1, 1} 00570 , 00571 {0x128, 3, 1, 2} 00572 }; 00573 00574 resolution.top = res; 00575 resolution.bottom = 1; 00576 if (write (fd, (char *) &type, sizeof type) != sizeof type 00577 || type != INTEL && type != MOTO) { 00578 WRITEFAILED.error ("write_tif_image", LOG, "Filetype"); 00579 return -1; 00580 } 00581 start = START; 00582 entries = 0x002a; 00583 if (type != __NATIVE__) 00584 entries = reverse16 (entries); 00585 if (write (fd, (char *) &entries, sizeof entries) != sizeof entries) { 00586 WRITEFAILED.error ("write_tif_image", LOG, "Version"); 00587 return -1; 00588 } 00589 if (type != __NATIVE__) 00590 start = reverse32 (start); 00591 if (write (fd, (char *) &start, sizeof start) != sizeof start) { 00592 WRITEFAILED.error ("write_tif_image", LOG, "Start"); 00593 return -1; 00594 } 00595 lseek (fd, (long) START, 0); 00596 entries = ENTRIES; 00597 if (type != __NATIVE__) 00598 entries = reverse16 (entries); 00599 if (write (fd, (char *) &entries, sizeof entries) != sizeof entries) { 00600 WRITEFAILED.error ("write_tif_image", LOG, "Entries"); 00601 return -1; 00602 } 00603 //line length 00604 size = COMPUTE_IMAGE_XDIM (xsize, bpp); 00605 size *= ysize; //total image size 00606 // if (photo==0) 00607 // { 00608 // tags[0].tag=0xfe; 00609 // tags[0].type=4; 00610 // tags[0].value=0; 00611 // } 00612 // else 00613 // { 00614 // tags[0].tag=0xff; 00615 // tags[0].type=3; 00616 // tags[0].value=1; 00617 // } 00618 tags[1].value = xsize; 00619 tags[2].value = ysize; 00620 if (bpp == 24) { 00621 tags[3].value = 8; 00622 tags[10].value = 3; 00623 tags[5].value = 2; 00624 } 00625 else { 00626 tags[3].value = bpp; 00627 tags[5].value = photo; 00628 } 00629 tags[11].value = ysize; 00630 tags[14].value = (1 << bpp) - 1; 00631 tags[12].value = size; 00632 for (entries = 0; entries < ENTRIES; entries++) { 00633 entry = tags[entries]; //get an entry 00634 /* NB Convert entry.value BEFORE converting entry.type!!! */ 00635 if (entry.type != 3) { //Full 32bit value 00636 if (type != __NATIVE__) 00637 entry.value = reverse32 (entry.value); 00638 } 00639 else { 00640 /* A 16bit value in 4 bytes - handle with care. 00641 SEE NOTE at start of file */ 00642 entry.value &= 0x0000ffff; //Ensure top 2 MSBytes clear 00643 if (__NATIVE__ == MOTO) { 00644 if (type == MOTO) //MOTO file on MOTO Machine 00645 entry.value = entry.value << 16; 00646 else //INTEL file on MOTO Machine 00647 entry.value = reverse32 (entry.value); 00648 } 00649 else { //INTEL Machine 00650 if (type == MOTO) //MOTO file on INTEL Machine 00651 entry.value = reverse16 ((UINT16) entry.value); 00652 //INTEL file on INTEL Machine NO ACTION NEEDED 00653 } 00654 } 00655 if (type != __NATIVE__) { 00656 entry.tag = reverse16 (entry.tag); 00657 entry.type = reverse16 (entry.type); 00658 entry.length = reverse32 (entry.length); 00659 } 00660 if (write (fd, (char *) &entry, sizeof (TIFFENTRY)) != 00661 sizeof (TIFFENTRY)) { 00662 WRITEFAILED.error ("write_tif_image", LOG, "Tag Table"); 00663 return -1; 00664 } 00665 } 00666 if (write (fd, (char *) &zero, sizeof zero) != sizeof zero) { 00667 WRITEFAILED.error ("write_tif_image", LOG, "Tag table Terminator"); 00668 return -1; 00669 } 00670 if (type != __NATIVE__) { 00671 resolution.top = reverse32 (resolution.top); 00672 resolution.bottom = reverse32 (resolution.bottom); 00673 } 00674 if (write (fd, (char *) &resolution, sizeof resolution) != sizeof resolution 00675 || write (fd, (char *) &resolution, 00676 sizeof resolution) != sizeof resolution) { 00677 WRITEFAILED.error ("write_tif_image", LOG, "Resolution"); 00678 return -1; 00679 } 00680 if (write (fd, (char *) pixels, (size_t) size) != size) { 00681 WRITEFAILED.error ("write_tif_image", LOG, "Image"); 00682 return -1; 00683 } 00684 close(fd); 00685 return 0; 00686 }