home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Der Mediaplex Sampler - Die 6 von Plex
/
6_v_plex.zip
/
6_v_plex
/
DISK5
/
WIN_12
/
IDEPIX2.ZIP
/
TIFFACS.ZIP
/
READIMAG.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-26
|
18KB
|
705 lines
/*-------------------------------------------------------
T I F F A C S : Unterstⁿtzungsroutinen fⁿr TIFF-Dateien
Ursprⁿnglich von Aldus, von mir auf dem
Walnut-Creek - Source-Code-ROM gefunden.
Der ursprⁿngliche Source ist TIFF 4.0 und
auch ansonsten ein ziemlicher Mⁿll.
Diese Version hat Funktionsprototypen und
ein paar Fehler weniger, aber im Grunde ist
sie auch ein ziemlicher Mⁿll.
Im Mircosoft System Journal 4/93 ist eine ganz
brauchbare TIF-Routine dabei, aber eben nicht PD
Bernd Herd
Rudolf Virchow Str. 8
6842 Bⁿrstadt
06206/79222
R E A D I M A G :read_imag liest einen Bildausschnitt aus
der TIFF-Datei, streifenⁿbergreifend,
dekomprimierend...
-------------------------------------------------------------*/
/* 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 <windows.h>
#include <io.h>
#include <string.h>
#pragma hdrstop
#include "tiff.h"
#include "tiffi.h"
//----------------- Funktionsprototypen -----------------------
int image_att_read(SHORT fhandle, SHORT fdtype);
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 DWORD width;
static DWORD 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 */
LONG read_image( SHORT fhandle, // Dateihandle der offenen TIF-Datei
SHORT fdtype, // zu lesender Subfile-Typ
SHORT plane, // Gerade zu bearbeitendes Plane (Farbebene)
LONG startpos, // 1. zu bearbeitende Zeile
LONG numlines, // Anzahl zu bearbeitende Zeilen
LONGPTR buffer, // Ergebnispuffer
LONG max_length) // Gr÷▀e der Puffers
{
/* 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 */
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 PACK_TIGHTLY:
/* 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_MOD_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,(SHORT) 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;
case PACKBITS: // Packbits-Kompression
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;
}
if ( !UnpackBits( decblk2, decblk, temp * bytes_per_line) )
return 0;
/* 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 PACK_TIGHTLY:
/* 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;
if( // lseek(fhandle,buffer,so_table[start_strip]) // sieht unsinnig aus ...
lseek(fhandle,so_table[start_strip],0) // so vielleicht besser ?
!= 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_MOD_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,(SHORT) 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,(SHORT) 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,(SHORT) width,
temp,sbc_table[end_strip]);
bigcopy(buffer,decblk,endoffset+bytes_per_line);
break;
case PACKBITS:
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;
}
if ( !UnpackBits( decblk2, decblk, temp * bytes_per_line) ) {
readimg_handle = -1;
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;
}
if ( !UnpackBits( decblk2, decblk, temp * bytes_per_line) ) {
readimg_handle = -1;
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;
}
if ( !UnpackBits( decblk2, decblk, temp * bytes_per_line) ) {
readimg_handle = -1;
return(0);
}
bigcopy(buffer,decblk,endoffset+bytes_per_line);
break;
}
}
return(numlines);
}
/* read all the tags so we can decipher this muther */
int image_att_read(SHORT fhandle, SHORT fdtype)
{
TIFF_DIR_ENTRY dirent;
LONG strip_offset;
LONG bytes_to_read;
LONG i;
if(!read_tag(fhandle,fdtype,IMAGE_WIDTH_TAG,
(LONGPTR)&width,(SHORT)LONG_SIZE)) {
/* failure in reading tag */
readimg_handle = -1;
return(0);
}
if(!read_tag(fhandle,fdtype,IMAGE_LENGTH_TAG,
(LONGPTR)&height,(SHORT)LONG_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] = dirent.value_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; //Mies!
}
if(one_strip_image)
sbc_table [0] = dirent.value_offset;
else {
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_MOD_HUFFMAN ||
l_compression == PACKBITS) {
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);
}