home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / disptiff / readimag.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-27  |  13.6 KB  |  554 lines

  1. /* the new improved read image.  Reads and holds in memory the strip
  2.    tables.  Should be 40-50 percent faster than the old readimage */
  3.  
  4. /* modified 1/12/88 by BGM  To handle default tag values for various */
  5. /* nonessiential tags and motorola files.  To become compatable with */
  6. /* proposed tiff specification, Still need to add code which will    */
  7. /* simulate the presense of the Strip byte count tables.             */
  8.  
  9. #include "tiff.h"
  10.  
  11. #define ONE_D_MODIFIED_HUFFMAN    2
  12.  
  13. LONG far *sbc_table = 0;
  14. LONG far *so_table = 0;
  15. LONGPTR    decblk = 0;
  16. LONGPTR decblk2 = 0;
  17. SHORT    l_compression = 0;
  18.  
  19. LONG    maxbytesstrip = 0;
  20.  
  21. extern SHORT    readimg_handle;
  22. static    SHORT    width;
  23. static    SHORT    height;
  24. static    SHORT    bits_per_sample;
  25. static    SHORT    samples_per_pixel;
  26. static    LONG    rows_per_strip;
  27. static    SHORT    bytes_per_line;
  28. static     LONG    number_strips;
  29. static  LONG    end_strip_lines;        /* lines in last strip */
  30. static  LONG    old_start;
  31. static    SHORT    one_strip_image;
  32.  
  33.  
  34. /* function return values */
  35. extern LONG lseek();
  36. extern SHORT tlRead();
  37. extern SHORT read();
  38. extern LONGPTR    bigalloc();
  39. extern void bigfree();
  40. extern SHORT read_dirent();
  41. extern SHORT read_tag();
  42. LONG    decompress_block();
  43. void    bigcopy();
  44. void    reorder();
  45.  
  46. LONG read_image(fhandle,fdtype,plane,startpos,numlines,buffer,max_length)
  47. SHORT    fhandle;
  48. SHORT    fdtype;
  49. SHORT    plane;
  50. LONG    startpos;
  51. LONG    numlines;
  52. LONGPTR    buffer;
  53. LONG    max_length;
  54. {
  55.     /* define the attributes of this image */
  56.  
  57. LONG    start_strip;
  58. LONG    end_strip;
  59. LONG    startoffset;
  60. LONG    endoffset;
  61. LONG    seek_addr;
  62. LONG    bytes_to_read;
  63. LONG ldc;        /* length decompressed */
  64. LONG    temp;
  65. LONG    endflag;    /* use the end_strip_lines variable */
  66.  
  67. int image_att_read();
  68.  
  69. if(fhandle != readimg_handle) {  /* first time through */
  70.                 /* with this image */
  71.  
  72.     readimg_handle = fhandle;
  73.  
  74.     /* go get the attributes of this image */
  75.  
  76.     if(!image_att_read(fhandle,fdtype)) {
  77.         return(0);
  78.     }
  79.     /* find out how many lines are in the last strip */
  80.     if((end_strip_lines = (height-1) % rows_per_strip) == 0 ) {
  81.         end_strip_lines = rows_per_strip;
  82.     }
  83.  
  84. } /* and that concludes the set up processing */
  85.  
  86. /* once the setup processing is done, start computing the parameters
  87.     for this particular read */
  88.  
  89.  
  90. /* compute strip number to start reading at */
  91.  
  92. start_strip = startpos/rows_per_strip;
  93. startoffset = (LONG)(startpos%rows_per_strip) * bytes_per_line;
  94.  
  95. /* compute end strip */
  96.  
  97. end_strip = (startpos +numlines-1) /rows_per_strip;
  98. endoffset = ((startpos + numlines-1) % rows_per_strip) * bytes_per_line;
  99.  
  100. /* make sure that the user has not asked for more that 64k of data */
  101. /* and that both strips are contained in the file */
  102.  
  103. endflag = 0;
  104. if(end_strip >= number_strips-1) {
  105.     end_strip = number_strips -1;
  106.     endflag = 1;
  107. }
  108.  
  109. if(start_strip> number_strips)
  110.     return(0);
  111.  
  112. if((temp = numlines * bytes_per_line) > max_length )
  113.     return(0);
  114.  
  115. if(temp > 65535)
  116.     return(0);
  117.  
  118. /* now read in the data.  There are 8 cases that can occure during 
  119.        a read.  they are:
  120.  
  121.     1. strip uncompressed, rows contained in one strip.
  122.     2. strip uncompressed, rows consume one strip
  123.     3. strip uncompressed, rows cross strip boundry
  124.     4. strip uncompressed, rows cross more than one strip
  125.         boundry.
  126.  
  127.     5. strip compressed, rows contained in one strip.
  128.     6. strip compressed, rows consume one strip
  129.     7. strip compressed, rows cross strip boundry.
  130.     8. strip compressed, rows cross more than one strip
  131.         boundry.
  132.  
  133. have I forgot any thing?  The method of reading chosen here,
  134. allows future compression schemes to be added to the routine
  135. very easily.
  136.  */
  137.  
  138. if(start_strip == end_strip) {
  139.     /* the requested image rows are contained in the same 
  140.         strip */
  141.     switch(l_compression) {  /* do things differently */
  142.                 /* if the image is compressed */
  143.     case 1:
  144.         /* read just the bytes needed.  case 1 is no */
  145.         /* compression */
  146.         /* compute seek address */
  147.         seek_addr = so_table[start_strip] + startoffset;
  148.         if(lseek(fhandle,seek_addr,0) != seek_addr) {
  149.             /* error in reading file */
  150.             return(0);
  151.         }
  152.  
  153.         bytes_to_read= endoffset - startoffset + bytes_per_line; 
  154.  
  155.         if(tlRead(fhandle,buffer,(SHORT)bytes_to_read)!=(SHORT)bytes_to_read) {
  156.             /* error in reading file */
  157.             return(0);
  158.         }
  159.         break;
  160.  
  161.     case ONE_D_MODIFIED_HUFFMAN:
  162.         if(start_strip != old_start) {
  163.             old_start = start_strip;
  164.             seek_addr = so_table[start_strip];
  165.  
  166.             if(lseek(fhandle,seek_addr,0) != seek_addr) {
  167.                 /* error in reading file */
  168.                 return(0);
  169.             }
  170.             
  171.             if(tlRead(fhandle,decblk2,(SHORT)sbc_table[start_strip])
  172.                      != (SHORT)sbc_table[start_strip]){
  173.                 /* error in reading the file */
  174.                 return(0);
  175.             }
  176.     
  177.     /* now, decompress the buffer */
  178.  
  179.             if(endflag && start_strip == number_strips -1) {
  180.                 temp = end_strip_lines;
  181.             } else {
  182.                 temp = rows_per_strip;
  183.             }
  184.  
  185.             ldc = decompress_block(decblk,decblk2,width,
  186.                 temp,sbc_table[start_strip]);
  187.  
  188.     /* check here to make sure that the compression 
  189.      * algorithim decompressed the entire strip */
  190.  
  191.             if(ldc != temp * bytes_per_line) {
  192.                 return(0);
  193.             }
  194.         }
  195.     /* the block is in memory already */
  196.     /* so just move the requested line out */        
  197.  
  198.         bigcopy(buffer,(LONGPTR)&decblk[startoffset],
  199.             endoffset - startoffset + bytes_per_line);
  200.         break;
  201.     }
  202. } else {
  203.     /* requested rows cross strip boundry. */
  204.     /* position file pointer to requested start strip */
  205.     switch(l_compression) {  /* do things differently */
  206.                 /* if the image is compressed */
  207.     case 1:
  208.         /* read from the start address, to the end of the strip */
  209.         /* compute seek address */
  210.         seek_addr = so_table[start_strip] + startoffset;
  211.         if(lseek(fhandle,seek_addr,0) != seek_addr) {
  212.             /* error in reading file */
  213.             return(0);
  214.         }
  215.  
  216.         bytes_to_read= sbc_table[start_strip] - startoffset;
  217.  
  218.         if(tlRead(fhandle,buffer,(SHORT)bytes_to_read)!=(SHORT)bytes_to_read) {
  219.             /* error in reading file */
  220.             return(0);
  221.         }
  222.  
  223.         /* update the buffer to point to */
  224.         /* the next area to read */
  225.  
  226.         buffer += bytes_to_read;
  227.  
  228.         /* now read as many strips as needed to get the
  229.          * required lines */
  230.  
  231.         for(start_strip++;start_strip<end_strip;start_strip++) {
  232.             if(lseek(fhandle,so_table[start_strip],0)
  233.                      != so_table[start_strip]){
  234.                 /* seek failed, return bad */
  235.                 return(0);
  236.             }
  237.  
  238.             if((LONG)tlRead(fhandle,buffer,sbc_table[start_strip])
  239.                      != sbc_table[start_strip]) {
  240.                 /* read failed, return bad */
  241.                 return(0);
  242.             }
  243.  
  244.             buffer += sbc_table[start_strip];
  245.         }
  246.  
  247.         /* now read the tail end */
  248.  
  249.         bytes_to_read = endoffset * bytes_per_line + bytes_per_line;
  250.  
  251.         if(lseek(fhandle,buffer,so_table[start_strip])
  252.              != so_table[start_strip]){
  253.             /* seek failed */
  254.             return(0);
  255.         }
  256.  
  257.         if(tlRead(fhandle,buffer,(SHORT)bytes_to_read)!=(SHORT)bytes_to_read) {
  258.             /* bad read */
  259.             return(0);
  260.         }
  261.         break;
  262.  
  263.     case ONE_D_MODIFIED_HUFFMAN:
  264.         seek_addr = so_table[start_strip];
  265.  
  266.         if(lseek(fhandle,seek_addr,0) != seek_addr) {
  267.             /* error in reading file */
  268.             return(0);
  269.         }
  270.         
  271.         if((LONG)tlRead(fhandle,decblk2,sbc_table[start_strip])
  272.             != sbc_table[start_strip]){
  273.             /* error in reading the file */
  274.             return(0);
  275.         }
  276.  
  277. /* now, decompress the buffer */
  278.  
  279.         
  280.         if(endflag && start_strip == number_strips -1) {
  281.             temp = end_strip_lines;
  282.         } else {
  283.             temp = rows_per_strip;
  284.         }
  285.         ldc = decompress_block(decblk,decblk2,width,
  286.                 temp,sbc_table[start_strip]);
  287.  
  288. /* check here to make sure that the compression algorithim
  289.  * decompressed the entire strip */
  290.  
  291.         if(ldc != temp * bytes_per_line) {
  292.             return(0);
  293.         }
  294.  
  295.         
  296.         /* move the starting part of the buffer to memory */
  297.  
  298.         bigcopy(buffer,(LONGPTR)&decblk[startoffset],ldc - startoffset);
  299.         buffer += ldc - startoffset;
  300.  
  301.         for(start_strip++;start_strip<end_strip;start_strip++) {
  302.             if(lseek(fhandle,so_table[start_strip],0) !=
  303.                     so_table[start_strip]) {
  304.             /* error in positioning the file */
  305.                 return(0);
  306.             }
  307.             if(tlRead(fhandle,decblk2,(SHORT)sbc_table[start_strip])!=
  308.                         (SHORT)sbc_table[start_strip]) {
  309.                 /* read failed */
  310.                 return(0);
  311.             }
  312.             if(endflag && start_strip == number_strips -1) {
  313.                 temp = end_strip_lines;
  314.             } else {
  315.                 temp = rows_per_strip;
  316.             }
  317.             ldc = decompress_block(decblk,decblk2,width,
  318.                     temp,sbc_table[start_strip]);
  319.             if(ldc != temp * bytes_per_line) {
  320.                 return(0);
  321.             }
  322.             bigcopy(buffer,(LONGPTR)&decblk[startoffset],ldc);
  323.  
  324.             buffer += ldc;
  325.         }
  326.  
  327.         /* now read the partial strip */
  328.  
  329.         if(lseek(fhandle,so_table[end_strip],0) !=
  330.                         so_table[end_strip]) {
  331.         /* error in positioning the file */
  332.             return(0);
  333.         }
  334.         if(tlRead(fhandle,decblk2,(SHORT)sbc_table[end_strip]) !=
  335.                     (SHORT)sbc_table[end_strip]) {
  336.             /* read failed */
  337.             return(0);
  338.         }
  339.  
  340.         if(endflag && end_strip == number_strips -1) {
  341.             temp = end_strip_lines;
  342.         } else {
  343.             temp = rows_per_strip;
  344.         }
  345.         ldc = decompress_block(decblk,decblk2,width,
  346.                 temp,sbc_table[end_strip]);
  347.  
  348.         bigcopy(buffer,decblk,endoffset+bytes_per_line);
  349.         break;
  350.         }
  351.     }
  352. return(numlines);
  353. }
  354.  
  355.     
  356. /* read all the tags so we can decipher this muther */
  357.  
  358. int image_att_read(fhandle,fdtype)
  359. SHORT fhandle;
  360. SHORT fdtype;
  361. {
  362.     TIFF_DIR_ENTRY dirent;
  363.     LONG    strip_offset;
  364.     LONG    bytes_to_read;
  365.     SHORT    tlRead();
  366.     LONG i;
  367.  
  368.     if(!read_tag(fhandle,fdtype,IMAGE_WIDTH_TAG,
  369.         (LONGPTR)&width,(SHORT)SHORT_SIZE)) {
  370.         /* failure in reading tag */
  371.         readimg_handle = -1;
  372.         return(0);
  373.     }
  374.  
  375.     if(!read_tag(fhandle,fdtype,IMAGE_LENGTH_TAG,
  376.         (LONGPTR)&height,(SHORT)SHORT_SIZE)) {
  377.         /* failure in reading tag */
  378.         readimg_handle = -1;
  379.         return(0);
  380.     }
  381.  
  382.     if(!read_tag(fhandle,fdtype,BITS_PER_SAMPLE_TAG,
  383.         (LONGPTR)&bits_per_sample,(SHORT)SHORT_SIZE)) {
  384.         /* read tag failed, set bits_per_sample to 1 */
  385.         bits_per_sample = 1;
  386.     }
  387.  
  388.     if(!read_tag(fhandle,fdtype,SAMPLES_PER_PIXEL_TAG,
  389.         (LONGPTR)&samples_per_pixel,(SHORT)SHORT_SIZE)) {
  390.         /* read tag failed, set samples_per_pixel to 1 */
  391.         samples_per_pixel = 1;
  392.     }
  393.     
  394.     if(!read_tag(fhandle,fdtype,ROWS_PER_STRIP_TAG,
  395.         (LONGPTR)&rows_per_strip,(SHORT)LONG_SIZE)) {
  396.         /* read tag failed, set value to img height */
  397.         rows_per_strip = height;
  398.     }
  399.  
  400.     bytes_per_line = ((width * bits_per_sample * samples_per_pixel)
  401.             +7) / 8;
  402.  
  403.     if(rows_per_strip == height) {  /* one strip per image */
  404.         one_strip_image = TRUE;
  405.     } else {
  406.         one_strip_image = FALSE;
  407.     }
  408.  
  409.     if(!read_tag(fhandle,fdtype,COMPRESSION_TAG,
  410.         (LONGPTR)&l_compression,(SHORT)SHORT_SIZE)) {
  411.         /* if read tag fails, set compression to */
  412.         /* 1 */
  413.         l_compression = 1;
  414.         /* this is type 1 pack as many pixels into a */
  415.         /* byte as possible */
  416.     }
  417.  
  418.  
  419.     /* now read in the directory entry for the strip offset */
  420.     /* tag. */
  421.  
  422.     if(!read_dirent(fhandle,fdtype,STRIP_OFFSETS_TAG,
  423.         (TIFF_DIR_ENTRY far *)&dirent)) {
  424.         /* read_dirent failed, return 0 */
  425.         readimg_handle = -1;
  426.         return(0);
  427.     }
  428.  
  429.     number_strips = dirent.length;
  430.     old_start = number_strips+1;
  431.     strip_offset = dirent.value_offset;
  432.         
  433.     /* allocate space for the strip table */
  434.     /* this memory will need to be freed by the */
  435.     /* close_read function */
  436.     /* the +1 is so that we have room to compute the strip tables */
  437.     /* if we need to. */
  438.  
  439.     bytes_to_read = number_strips * (LONG)LONG_SIZE;
  440.  
  441.     so_table = (LONG far *)bigalloc(bytes_to_read + sizeof(long));
  442.     sbc_table = (LONG far *)bigalloc(bytes_to_read + sizeof (long));
  443.  
  444.  
  445.     if(!so_table) {
  446.         readimg_handle = -1;
  447.         return(0);
  448.     }
  449.     
  450.     if(!sbc_table) {
  451.         bigfree(so_table);
  452.         so_table = 0;
  453.         readimg_handle = -1;
  454.         return(0);
  455.     }
  456.     
  457.     if(one_strip_image) {
  458.         so_table[0] = strip_offset;
  459.         sbc_table[0] = bytes_per_line * height;
  460.     } else {
  461.         if(lseek(fhandle,strip_offset,0) != strip_offset) {
  462.             readimg_handle = -1;
  463.             bigfree(so_table);
  464.             so_table = 0;
  465.             return(0);
  466.         }
  467.     
  468.         if(tlRead(fhandle,so_table,(SHORT)bytes_to_read) != (short)bytes_to_read) {
  469.             readimg_handle = -1;
  470.             bigfree(so_table);
  471.             so_table = 0;
  472.             return(0);
  473.         }
  474.  
  475.         /* now check the originator and swap the bytes if */
  476.         /* necessary */
  477.         for(i=0;i<number_strips;i++) {
  478.             reorder((LONG far *)&so_table[i],LONG_SIZE);
  479.         }
  480.     
  481.         /* now read the strip byte count tables */
  482.         /* if the strip byte count table is not present, then */
  483.         /* we need to fudge the data by using the strip offsets */
  484.         /* to compute the strip byte counts */
  485.     
  486.         
  487.         if(!read_dirent(fhandle,fdtype,STRIP_BYTE_COUNTS_TAG,
  488.             (TIFF_DIR_ENTRY far *)&dirent)) {
  489.             /* read_dirent failed, fudge the data */
  490.             so_table[number_strips+1] = bytes_per_line *
  491.                 height - so_table[0];
  492.             for(i=0;i<number_strips;i++) {
  493.                 sbc_table[i] = so_table[i+1] -
  494.                          so_table[i];
  495.             }
  496.             goto NOREAD_STRIP_COUNTS;
  497.         }
  498.     
  499.         strip_offset = dirent.value_offset;
  500.     
  501.     
  502.         if(lseek(fhandle,strip_offset,0) != strip_offset) {
  503.             readimg_handle = -1;
  504.             bigfree(so_table);
  505.             so_table = 0;
  506.             bigfree(sbc_table);
  507.             sbc_table = 0;
  508.             return(0);
  509.             }
  510.     
  511.     
  512.         if(tlRead(fhandle,sbc_table,(SHORT)bytes_to_read) != (SHORT)bytes_to_read) {
  513.             readimg_handle = -1;
  514.             bigfree(so_table);
  515.             so_table = 0;
  516.             bigfree(sbc_table);
  517.             sbc_table = 0;
  518.             return(0);
  519.         }
  520.  
  521.         /* swap the bytes if necessary */
  522.         for(i=0;i<number_strips;i++) {
  523.             reorder((LONG far *)&sbc_table[i],LONG_SIZE);
  524.         }
  525.             
  526.     }
  527. NOREAD_STRIP_COUNTS:
  528. /* find the biggest strip and allocate memory for it */    
  529.  
  530.     maxbytesstrip = 0;
  531.     for(i=0; i < number_strips; i++) {
  532.         if(maxbytesstrip < sbc_table[i] ) {
  533.             maxbytesstrip = sbc_table[i];
  534.         }
  535.     }
  536.     
  537.     if(l_compression == ONE_D_MODIFIED_HUFFMAN) {
  538.         decblk2 = (LONGPTR) bigalloc(maxbytesstrip);
  539.         if(decblk2 == (LONGPTR)0){
  540.             return(0);
  541.         }
  542.         decblk=(LONGPTR)bigalloc((rows_per_strip+1) *  bytes_per_line);
  543.         if(decblk == (LONGPTR)0) {
  544.             bigfree(decblk2);
  545.             return(0);
  546.         }
  547.     }
  548.     return(1);
  549. }
  550.  
  551. dummproc()
  552. {
  553. }
  554.