home *** CD-ROM | disk | FTP | other *** search
- /* the new improved read image. Reads and holds in memory the strip
- tables. Should be 40-50 percent faster than the old readimage */
-
- /* modified 1/12/88 by BGM To handle default tag values for various */
- /* nonessiential tags and motorola files. To become compatable with */
- /* proposed tiff specification, Still need to add code which will */
- /* simulate the presense of the Strip byte count tables. */
-
- #include "tiff.h"
-
- #define ONE_D_MODIFIED_HUFFMAN 2
-
- LONG far *sbc_table = 0;
- LONG far *so_table = 0;
- LONGPTR decblk = 0;
- LONGPTR decblk2 = 0;
- SHORT l_compression = 0;
-
- LONG maxbytesstrip = 0;
-
- extern SHORT readimg_handle;
- static SHORT width;
- static SHORT height;
- static SHORT bits_per_sample;
- static SHORT samples_per_pixel;
- static LONG rows_per_strip;
- static SHORT bytes_per_line;
- static LONG number_strips;
- static LONG end_strip_lines; /* lines in last strip */
- static LONG old_start;
- static SHORT one_strip_image;
-
-
- /* function return values */
- extern LONG lseek();
- extern SHORT tlRead();
- extern SHORT read();
- extern LONGPTR bigalloc();
- extern void bigfree();
- extern SHORT read_dirent();
- extern SHORT read_tag();
- LONG decompress_block();
- void bigcopy();
- void reorder();
-
- LONG read_image(fhandle,fdtype,plane,startpos,numlines,buffer,max_length)
- SHORT fhandle;
- SHORT fdtype;
- SHORT plane;
- LONG startpos;
- LONG numlines;
- LONGPTR buffer;
- LONG max_length;
- {
- /* define the attributes of this image */
-
- LONG start_strip;
- LONG end_strip;
- LONG startoffset;
- LONG endoffset;
- LONG seek_addr;
- LONG bytes_to_read;
- LONG ldc; /* length decompressed */
- LONG temp;
- LONG endflag; /* use the end_strip_lines variable */
-
- int image_att_read();
-
- if(fhandle != readimg_handle) { /* first time through */
- /* with this image */
-
- readimg_handle = fhandle;
-
- /* go get the attributes of this image */
-
- if(!image_att_read(fhandle,fdtype)) {
- return(0);
- }
- /* find out how many lines are in the last strip */
- if((end_strip_lines = (height-1) % rows_per_strip) == 0 ) {
- end_strip_lines = rows_per_strip;
- }
-
- } /* and that concludes the set up processing */
-
- /* once the setup processing is done, start computing the parameters
- for this particular read */
-
-
- /* compute strip number to start reading at */
-
- start_strip = startpos/rows_per_strip;
- startoffset = (LONG)(startpos%rows_per_strip) * bytes_per_line;
-
- /* compute end strip */
-
- end_strip = (startpos +numlines-1) /rows_per_strip;
- endoffset = ((startpos + numlines-1) % rows_per_strip) * bytes_per_line;
-
- /* make sure that the user has not asked for more that 64k of data */
- /* and that both strips are contained in the file */
-
- endflag = 0;
- if(end_strip >= number_strips-1) {
- end_strip = number_strips -1;
- endflag = 1;
- }
-
- if(start_strip> number_strips)
- return(0);
-
- if((temp = numlines * bytes_per_line) > max_length )
- return(0);
-
- if(temp > 65535)
- return(0);
-
- /* now read in the data. There are 8 cases that can occure during
- a read. they are:
-
- 1. strip uncompressed, rows contained in one strip.
- 2. strip uncompressed, rows consume one strip
- 3. strip uncompressed, rows cross strip boundry
- 4. strip uncompressed, rows cross more than one strip
- boundry.
-
- 5. strip compressed, rows contained in one strip.
- 6. strip compressed, rows consume one strip
- 7. strip compressed, rows cross strip boundry.
- 8. strip compressed, rows cross more than one strip
- boundry.
-
- have I forgot any thing? The method of reading chosen here,
- allows future compression schemes to be added to the routine
- very easily.
- */
-
- if(start_strip == end_strip) {
- /* the requested image rows are contained in the same
- strip */
- switch(l_compression) { /* do things differently */
- /* if the image is compressed */
- case 1:
- /* read just the bytes needed. case 1 is no */
- /* compression */
- /* compute seek address */
- seek_addr = so_table[start_strip] + startoffset;
- if(lseek(fhandle,seek_addr,0) != seek_addr) {
- /* error in reading file */
- return(0);
- }
-
- bytes_to_read= endoffset - startoffset + bytes_per_line;
-
- if(tlRead(fhandle,buffer,(SHORT)bytes_to_read)!=(SHORT)bytes_to_read) {
- /* error in reading file */
- return(0);
- }
- break;
-
- case ONE_D_MODIFIED_HUFFMAN:
- if(start_strip != old_start) {
- old_start = start_strip;
- seek_addr = so_table[start_strip];
-
- if(lseek(fhandle,seek_addr,0) != seek_addr) {
- /* error in reading file */
- return(0);
- }
-
- if(tlRead(fhandle,decblk2,(SHORT)sbc_table[start_strip])
- != (SHORT)sbc_table[start_strip]){
- /* error in reading the file */
- return(0);
- }
-
- /* now, decompress the buffer */
-
- if(endflag && start_strip == number_strips -1) {
- temp = end_strip_lines;
- } else {
- temp = rows_per_strip;
- }
-
- ldc = decompress_block(decblk,decblk2,width,
- temp,sbc_table[start_strip]);
-
- /* check here to make sure that the compression
- * algorithim decompressed the entire strip */
-
- if(ldc != temp * bytes_per_line) {
- return(0);
- }
- }
- /* the block is in memory already */
- /* so just move the requested line out */
-
- bigcopy(buffer,(LONGPTR)&decblk[startoffset],
- endoffset - startoffset + bytes_per_line);
- break;
- }
- } else {
- /* requested rows cross strip boundry. */
- /* position file pointer to requested start strip */
- switch(l_compression) { /* do things differently */
- /* if the image is compressed */
- case 1:
- /* read from the start address, to the end of the strip */
- /* compute seek address */
- seek_addr = so_table[start_strip] + startoffset;
- if(lseek(fhandle,seek_addr,0) != seek_addr) {
- /* error in reading file */
- return(0);
- }
-
- bytes_to_read= sbc_table[start_strip] - startoffset;
-
- if(tlRead(fhandle,buffer,(SHORT)bytes_to_read)!=(SHORT)bytes_to_read) {
- /* error in reading file */
- return(0);
- }
-
- /* update the buffer to point to */
- /* the next area to read */
-
- buffer += bytes_to_read;
-
- /* now read as many strips as needed to get the
- * required lines */
-
- for(start_strip++;start_strip<end_strip;start_strip++) {
- if(lseek(fhandle,so_table[start_strip],0)
- != so_table[start_strip]){
- /* seek failed, return bad */
- return(0);
- }
-
- if((LONG)tlRead(fhandle,buffer,sbc_table[start_strip])
- != sbc_table[start_strip]) {
- /* read failed, return bad */
- return(0);
- }
-
- buffer += sbc_table[start_strip];
- }
-
- /* now read the tail end */
-
- bytes_to_read = endoffset * bytes_per_line + bytes_per_line;
-
- if(lseek(fhandle,buffer,so_table[start_strip])
- != so_table[start_strip]){
- /* seek failed */
- return(0);
- }
-
- if(tlRead(fhandle,buffer,(SHORT)bytes_to_read)!=(SHORT)bytes_to_read) {
- /* bad read */
- return(0);
- }
- break;
-
- case ONE_D_MODIFIED_HUFFMAN:
- seek_addr = so_table[start_strip];
-
- if(lseek(fhandle,seek_addr,0) != seek_addr) {
- /* error in reading file */
- return(0);
- }
-
- if((LONG)tlRead(fhandle,decblk2,sbc_table[start_strip])
- != sbc_table[start_strip]){
- /* error in reading the file */
- return(0);
- }
-
- /* now, decompress the buffer */
-
-
- if(endflag && start_strip == number_strips -1) {
- temp = end_strip_lines;
- } else {
- temp = rows_per_strip;
- }
- ldc = decompress_block(decblk,decblk2,width,
- temp,sbc_table[start_strip]);
-
- /* check here to make sure that the compression algorithim
- * decompressed the entire strip */
-
- if(ldc != temp * bytes_per_line) {
- return(0);
- }
-
-
- /* move the starting part of the buffer to memory */
-
- bigcopy(buffer,(LONGPTR)&decblk[startoffset],ldc - startoffset);
- buffer += ldc - startoffset;
-
- for(start_strip++;start_strip<end_strip;start_strip++) {
- if(lseek(fhandle,so_table[start_strip],0) !=
- so_table[start_strip]) {
- /* error in positioning the file */
- return(0);
- }
- if(tlRead(fhandle,decblk2,(SHORT)sbc_table[start_strip])!=
- (SHORT)sbc_table[start_strip]) {
- /* read failed */
- return(0);
- }
- if(endflag && start_strip == number_strips -1) {
- temp = end_strip_lines;
- } else {
- temp = rows_per_strip;
- }
- ldc = decompress_block(decblk,decblk2,width,
- temp,sbc_table[start_strip]);
- if(ldc != temp * bytes_per_line) {
- return(0);
- }
- bigcopy(buffer,(LONGPTR)&decblk[startoffset],ldc);
-
- buffer += ldc;
- }
-
- /* now read the partial strip */
-
- if(lseek(fhandle,so_table[end_strip],0) !=
- so_table[end_strip]) {
- /* error in positioning the file */
- return(0);
- }
- if(tlRead(fhandle,decblk2,(SHORT)sbc_table[end_strip]) !=
- (SHORT)sbc_table[end_strip]) {
- /* read failed */
- return(0);
- }
-
- if(endflag && end_strip == number_strips -1) {
- temp = end_strip_lines;
- } else {
- temp = rows_per_strip;
- }
- ldc = decompress_block(decblk,decblk2,width,
- temp,sbc_table[end_strip]);
-
- bigcopy(buffer,decblk,endoffset+bytes_per_line);
- break;
- }
- }
- return(numlines);
- }
-
-
- /* read all the tags so we can decipher this muther */
-
- int image_att_read(fhandle,fdtype)
- SHORT fhandle;
- SHORT fdtype;
- {
- TIFF_DIR_ENTRY dirent;
- LONG strip_offset;
- LONG bytes_to_read;
- SHORT tlRead();
- LONG i;
-
- if(!read_tag(fhandle,fdtype,IMAGE_WIDTH_TAG,
- (LONGPTR)&width,(SHORT)SHORT_SIZE)) {
- /* failure in reading tag */
- readimg_handle = -1;
- return(0);
- }
-
- if(!read_tag(fhandle,fdtype,IMAGE_LENGTH_TAG,
- (LONGPTR)&height,(SHORT)SHORT_SIZE)) {
- /* failure in reading tag */
- readimg_handle = -1;
- return(0);
- }
-
- if(!read_tag(fhandle,fdtype,BITS_PER_SAMPLE_TAG,
- (LONGPTR)&bits_per_sample,(SHORT)SHORT_SIZE)) {
- /* read tag failed, set bits_per_sample to 1 */
- bits_per_sample = 1;
- }
-
- if(!read_tag(fhandle,fdtype,SAMPLES_PER_PIXEL_TAG,
- (LONGPTR)&samples_per_pixel,(SHORT)SHORT_SIZE)) {
- /* read tag failed, set samples_per_pixel to 1 */
- samples_per_pixel = 1;
- }
-
- if(!read_tag(fhandle,fdtype,ROWS_PER_STRIP_TAG,
- (LONGPTR)&rows_per_strip,(SHORT)LONG_SIZE)) {
- /* read tag failed, set value to img height */
- rows_per_strip = height;
- }
-
- bytes_per_line = ((width * bits_per_sample * samples_per_pixel)
- +7) / 8;
-
- if(rows_per_strip == height) { /* one strip per image */
- one_strip_image = TRUE;
- } else {
- one_strip_image = FALSE;
- }
-
- if(!read_tag(fhandle,fdtype,COMPRESSION_TAG,
- (LONGPTR)&l_compression,(SHORT)SHORT_SIZE)) {
- /* if read tag fails, set compression to */
- /* 1 */
- l_compression = 1;
- /* this is type 1 pack as many pixels into a */
- /* byte as possible */
- }
-
-
- /* now read in the directory entry for the strip offset */
- /* tag. */
-
- if(!read_dirent(fhandle,fdtype,STRIP_OFFSETS_TAG,
- (TIFF_DIR_ENTRY far *)&dirent)) {
- /* read_dirent failed, return 0 */
- readimg_handle = -1;
- return(0);
- }
-
- number_strips = dirent.length;
- old_start = number_strips+1;
- strip_offset = dirent.value_offset;
-
- /* allocate space for the strip table */
- /* this memory will need to be freed by the */
- /* close_read function */
- /* the +1 is so that we have room to compute the strip tables */
- /* if we need to. */
-
- bytes_to_read = number_strips * (LONG)LONG_SIZE;
-
- so_table = (LONG far *)bigalloc(bytes_to_read + sizeof(long));
- sbc_table = (LONG far *)bigalloc(bytes_to_read + sizeof (long));
-
-
- if(!so_table) {
- readimg_handle = -1;
- return(0);
- }
-
- if(!sbc_table) {
- bigfree(so_table);
- so_table = 0;
- readimg_handle = -1;
- return(0);
- }
-
- if(one_strip_image) {
- so_table[0] = strip_offset;
- sbc_table[0] = bytes_per_line * height;
- } else {
- if(lseek(fhandle,strip_offset,0) != strip_offset) {
- readimg_handle = -1;
- bigfree(so_table);
- so_table = 0;
- return(0);
- }
-
- if(tlRead(fhandle,so_table,(SHORT)bytes_to_read) != (short)bytes_to_read) {
- readimg_handle = -1;
- bigfree(so_table);
- so_table = 0;
- return(0);
- }
-
- /* now check the originator and swap the bytes if */
- /* necessary */
- for(i=0;i<number_strips;i++) {
- reorder((LONG far *)&so_table[i],LONG_SIZE);
- }
-
- /* now read the strip byte count tables */
- /* if the strip byte count table is not present, then */
- /* we need to fudge the data by using the strip offsets */
- /* to compute the strip byte counts */
-
-
- if(!read_dirent(fhandle,fdtype,STRIP_BYTE_COUNTS_TAG,
- (TIFF_DIR_ENTRY far *)&dirent)) {
- /* read_dirent failed, fudge the data */
- so_table[number_strips+1] = bytes_per_line *
- height - so_table[0];
- for(i=0;i<number_strips;i++) {
- sbc_table[i] = so_table[i+1] -
- so_table[i];
- }
- goto NOREAD_STRIP_COUNTS;
- }
-
- strip_offset = dirent.value_offset;
-
-
- if(lseek(fhandle,strip_offset,0) != strip_offset) {
- readimg_handle = -1;
- bigfree(so_table);
- so_table = 0;
- bigfree(sbc_table);
- sbc_table = 0;
- return(0);
- }
-
-
- if(tlRead(fhandle,sbc_table,(SHORT)bytes_to_read) != (SHORT)bytes_to_read) {
- readimg_handle = -1;
- bigfree(so_table);
- so_table = 0;
- bigfree(sbc_table);
- sbc_table = 0;
- return(0);
- }
-
- /* swap the bytes if necessary */
- for(i=0;i<number_strips;i++) {
- reorder((LONG far *)&sbc_table[i],LONG_SIZE);
- }
-
- }
- NOREAD_STRIP_COUNTS:
- /* find the biggest strip and allocate memory for it */
-
- maxbytesstrip = 0;
- for(i=0; i < number_strips; i++) {
- if(maxbytesstrip < sbc_table[i] ) {
- maxbytesstrip = sbc_table[i];
- }
- }
-
- if(l_compression == ONE_D_MODIFIED_HUFFMAN) {
- decblk2 = (LONGPTR) bigalloc(maxbytesstrip);
- if(decblk2 == (LONGPTR)0){
- return(0);
- }
- decblk=(LONGPTR)bigalloc((rows_per_strip+1) * bytes_per_line);
- if(decblk == (LONGPTR)0) {
- bigfree(decblk2);
- return(0);
- }
- }
- return(1);
- }
-
- dummproc()
- {
- }