/* This file is distributed as public domain software for use in AVS only. Anyone may copy or modify this source code, as long as this header is kept intact and no charge is levied for the source code or executable. No warranty of any kind is provided. I would appreciate any major changes to the source and bug reports be sent to me. ------------------------------------------------------------------ ===== Richard Albrecht ======= albrecht@vms.biochem.mpg.de == -- Max-Planck-Institut | 0049 89 8578 2312 ph -- -- fuer Biochemie | 0049 89 8578 3885 fax -- ------------------------------------------------------------------ gtifread.c HighC 2.3 -- Copyright (c) 1994 -- R. Albrecht, MPI f. Biochemie, Martinsried */ /* -- TIFF uses 1, 2 and 4 byte unsigned Objects: BYTE, WORD and DWORD normally in ANSI C the following defines are used: BYTE: unsigned char ( 8 bits ) WORD: unsigned short ( 16 bits ) DWORD: unsigned long ( 32 bits ) The type 'int' is not recommended, because it is the default data type and machine dependent. At the DEC alpha's the situation is different: 'int' is only 32 bits and not 64 as expected. 'long' is 64 bits. Use the following define for the 'alphas': DWORD: unsigned int Some machines generate an error message during runtime, if a pointer is not aligned ( all DEC's ). All references to unaligned pointers are replaced with 'memcpy'. a = 'some place in the TIFF-buffer' b = *a --- is replaced by memcpy(&b,a,sizeof(b)); This is stable. */ #include #include #include /* -- MSDOS specific defines */ /* -- this define is only for my DOS-environment, don't use #define MS_DOS_USED */ /* -- DEC alpha DWORD */ /* #define DWORD_IS_UINT */ /* -- normal DWORD */ #define DWORD_IS_ULONG #ifdef MS_DOS_USED /* -- this is my private area */ #include #include #include #define err_file (syso.std_err) #define err_val (syso.err_val) #define RA_COPYR " Copyright (1994) R. Albrecht, MPI f. Biochemie " #define RA_COPYR_SIZE 50 #else /* -- UNIX specific defines */ #ifdef BYTE #undef BYTE #endif #define BYTE unsigned char #ifdef WORD #undef WORD #endif #define WORD unsigned short #ifdef DWORD #undef DWORD #endif #ifdef DWORD_IS_UINT #define DWORD unsigned int #else #define DWORD unsigned long #endif #include "tsystiff.h" #include "g_imhelp.h" #define err_file (stderr) int err_val = 0; extern int tiff_info_toggle; #endif static tsystif systif; int std_tiff_init_control = 0; /* -- byte reverse WORD and DWORD */ static void gtif_WORD_swab( WORD *buf ){ *buf = (( *buf << 8 ) & 0xff00) + ((*buf >> 8 ) & 0x00ff); } static void gtif_DWORD_swab( DWORD *buf ){ *buf = (( (*buf & 0x000000ff) << 24) & 0xff000000) + (( (*buf & 0x0000ff00) << 8) & 0x00ff0000) + (( (*buf & 0x00ff0000) >> 8) & 0x0000ff00) + (( (*buf & 0xff000000) >> 24) & 0x000000ff); } /* -- byte-reverse WORD or DWORD in a buffer */ static void gtif_WORD_arr_swab( WORD *b, int l ){ int lsave=l; WORD *buf=malloc(l*sizeof(WORD)); WORD *buf_save = buf; memcpy( buf,b,l*sizeof(WORD)); while( l-- ){ *buf = (( *buf << 8 ) & 0xff00) + ((*buf >> 8 ) & 0x00ff); buf++; } l=lsave; buf = buf_save; memcpy( b,buf,l*sizeof(WORD)); free(buf); } static void gtif_DWORD_arr_swab( DWORD *b, int l ){ int lsave = l; DWORD *buf=malloc(l*sizeof(DWORD)); DWORD *buf_save = buf; memcpy( buf,b,l*sizeof(DWORD)); while( l-- ){ *buf = (( (*buf & 0x000000ff) << 24) & 0xff000000) + (( (*buf & 0x0000ff00) << 8) & 0x00ff0000) + (( (*buf & 0x00ff0000) >> 8) & 0x0000ff00) + (( (*buf & 0xff000000) >> 24) & 0x000000ff); buf++; } l = lsave; buf = buf_save; memcpy( b,buf,l*sizeof(DWORD)); free(buf); } static int tiff_sizeof( WORD n ){ int ret = 0; switch( n ) { case byte: case ascii: ret = 1; break; case _short: ret = 2; break; case _long: ret = 4; break; case rational: ret = 8; break; default: ret = -1; break; } return ret; } static void gtiff_reverse_entry ( ttif_dir *source ){ BYTE *t_buf = systif.tif_file_buf; int err = 0; ttif_dir entry; DWORD bytes_to_read; DWORD val_pos; memcpy( &entry, source, sizeof( ttif_dir ) ); gtif_WORD_swab( (WORD*) (&(entry.tag) ) ); gtif_WORD_swab( (WORD*) (&(entry.type) ) ); gtif_DWORD_swab( (DWORD*)(&(entry.length) ) ); bytes_to_read = tiff_sizeof( entry.type ) * entry.length; if( bytes_to_read > 4L ){ gtif_DWORD_swab( (DWORD*)(&(entry.offset)) ); } switch( entry.type ){ case byte: case ascii: break; case _short: if( entry.length == 1 ){ gtif_WORD_swab( (WORD*)(&(entry.offset)) ); } if( entry.length == 2 ){ gtif_WORD_arr_swab( (WORD*)(&(entry.offset)), 2 ); } if( entry.length > 2 ){ gtif_WORD_arr_swab( (WORD*)(t_buf+entry.offset), entry.length ); } break; case _long: if( entry.length == 1 ){ gtif_DWORD_swab( (DWORD*)&(entry.offset) ); } else{ gtif_DWORD_arr_swab( (DWORD*)(t_buf+entry.offset), entry.length ); } break; case rational: gtif_DWORD_arr_swab( (DWORD*)(t_buf+entry.offset), 2 ); break; default: fprintf( err_file, "Reverse Tiff Entry: can't get here\n" ); exit(0); break; } memcpy( source, &entry, sizeof( ttif_dir ) ); } static void copy_to_BYTE_array( BYTE *img ){ ttif_par *ptiff = &(systif.tif_par); /* -- global */ DWORD bytes_per_strip = ptiff->rows_per_strip * ptiff->image_width; DWORD offset_faktor; DWORD bytes_copied = 0; if( ptiff->long_offset ) offset_faktor = 4; else offset_faktor = 2; if( ptiff->strips_per_image == 1 ){ memcpy( img, systif.tif_file_buf + ptiff->offset_strips, ptiff->rows_per_strip * ptiff->image_width ); } else{ DWORD offset; BYTE *poff; BYTE *pimg=img; DWORD i; DWORD last_count; poff = ( systif.tif_file_buf + ptiff->offset_strips ); for( i=0; i < ( ptiff->strips_per_image-1 ); i++ ){ if( ptiff->long_offset ){ memcpy( &offset, poff, sizeof( DWORD )); } else{ WORD a; memcpy( &a, poff, sizeof( WORD )); offset = (WORD)a; } memcpy( pimg, systif.tif_file_buf + offset, bytes_per_strip); pimg += bytes_per_strip; poff += offset_faktor; bytes_copied += bytes_per_strip; } /* -- last strip -- last count = img_size - read_size */ last_count = (ptiff->image_width * ptiff->image_length ) - ( bytes_per_strip * (ptiff->strips_per_image-1)); if( ptiff->long_offset ){ memcpy( &offset, poff, sizeof( DWORD )); } else{ WORD a; memcpy( &a, poff, sizeof( WORD )); offset = (DWORD)a; } memcpy( pimg, systif.tif_file_buf + offset, last_count ); } /* -- reverse image, if ph interpret == 0 */ if( ptiff->photometric_interpr == 0 ){ BYTE *pimg=img; BYTE *peimg = pimg + ptiff->rows_per_strip * ptiff->image_width ; while( pimg < peimg ){ *pimg = 0xff - *pimg; pimg++; } } } int g_scan_tif_entry( ttif_dir *e ){ ttif_par *tiff = &(systif.tif_par); int err; WORD tag; WORD type; DWORD length; DWORD offset; WORD s_offset; ttif_dir entry; int i; err = 0; memcpy( &entry, e, sizeof( ttif_dir ) ); if( systif.type == 1 ){ gtiff_reverse_entry ( &entry ); } tag = entry.tag; type = entry.type; length = entry.length; offset = entry.offset; s_offset = *((WORD*)(&entry.offset)); /* printf(" tag %04X\n",tag); printf(" type %d\n",type); printf(" length %08X\n",length); printf(" offset %08X\n\n",offset); printf(" s_offset %08X\n\n",s_offset); i=getchar(); */ switch( tag ){ /* -- new subfile type */ case 0xFE : if( type != _long ){ err = ((int)tag) * (-1); break; } if( length != 1 ){ err = ((int)tag) * (-1); break; } break; /* -- subfile type */ case 0xFF: break; /* -- Image Width */ case 0x100: if( type == _short ){ tiff->image_width = s_offset; break; } if( type == _long ){ tiff->image_width = offset; break; } err = ((int)tag) * (-1); break; /* -- Image Length */ case 0x101: if( type == _short ){ tiff->image_length = s_offset; break; } if( type == _long ){ tiff->image_length = offset; break; } err = ((int)tag) * (-1); break; /* -- Bits Per Sample */ case 0x102 : if( type == _short ){ if( length == 1 ){ tiff->bits_per_sample = s_offset; tiff->rgb_bits_per_sample.r = 0; tiff->rgb_bits_per_sample.g = 0; tiff->rgb_bits_per_sample.b = 0; break; } if( length == 3 ){ tiff->bits_per_sample = 0; memcpy( &(tiff->rgb_bits_per_sample.r), systif.tif_file_buf+offset, 2 ); memcpy( &(tiff->rgb_bits_per_sample.g), systif.tif_file_buf+offset+2, 2 ); memcpy( &(tiff->rgb_bits_per_sample.b), systif.tif_file_buf+offset+4, 2 ); break; } } err = ((int)tag) * (-1); break; /* -- Compression */ case 0x103 : if( type == _short ){ tiff->compression = s_offset; break; } err = ((int)tag) * (-1); break; /* -- Photometric Interpretation */ case 0x106 : if( type == _short ){ tiff->photometric_interpr = s_offset; break; } err = ((int)tag) * (-1); break; /* -- Document */ case 0x10D : if( type == ascii ){ if(offset > 0 && length > 0){ int len; if( tiff->doc ) free( tiff->doc ); len = strlen( (char *)(systif.tif_file_buf+offset) ); tiff->doc = malloc((len+1)*sizeof(char)); strcpy( tiff->doc, (char *)(systif.tif_file_buf+offset) ); } break; } err = ((int)tag) * (-1); break; /* -- Description */ case 0x10E : if( type == ascii ){ if(offset > 0 && length > 0 ){ int len; if( tiff->name ) free( tiff->name ); len = strlen( (char *)(systif.tif_file_buf+offset) ); tiff->name = malloc((len+1)*sizeof(char)); strcpy( tiff->name, (char *)(systif.tif_file_buf+offset) ); } break; } err = ((int)tag) * (-1); break; /* -- Make */ case 0x10F : if( type == ascii ){ if(offset > 0 && length > 0 ){ int len; if( tiff->make ) free( tiff->make ); len = strlen( (char *)(systif.tif_file_buf+offset) ); tiff->make = malloc((len+1)*sizeof(char)); strcpy( tiff->make, (char *)(systif.tif_file_buf+offset) ); } break; } err = ((int)tag) * (-1); break; /* -- Model */ case 0x110 : if( type == ascii ){ if(offset > 0 && length > 0){ int len; if( tiff->model ) free( tiff->model ); len = strlen( (char *)(systif.tif_file_buf+offset) ); tiff->model = malloc((len+1)*sizeof(char)); strcpy( tiff->model, (char *)(systif.tif_file_buf+offset) ); } break; } err = ((int)tag) * (-1); break; /* -- Strip offsets */ case 0x111 : if( type == _long ){ tiff->strips_per_image = length; tiff->long_offset = 1; tiff->offset_strips = offset; break; } if( type == _short ){ tiff->strips_per_image = length; tiff->long_offset = 0; tiff->offset_strips = s_offset; break; } err = ((int)tag) * (-1); break; /* -- Samples per Pixel */ case 0x115 : if( type == _short ){ tiff->samples_per_pixel = s_offset; break; } err = ((int)tag) * (-1); break; /* -- Rows Per Strip */ case 0x116 : if( type == _long ){ tiff->rows_per_strip = offset; break; } if( type == _short ){ tiff->rows_per_strip = s_offset; break; } err = ((int)tag) * (-1); break; /* -- Strip Byte Counts */ case 0x117 : break; /* -- X-Resolution */ case 0x11A : if( type == rational ){ memcpy( &(tiff->x_numerator), systif.tif_file_buf+offset,4); memcpy( &(tiff->x_denominator), systif.tif_file_buf+offset+4,4); break; } err = ((int)tag) * (-1); break; /* -- Y-Resolution */ case 0x11B : if( type == rational ){ memcpy( &(tiff->y_numerator), systif.tif_file_buf+offset,4); memcpy( &(tiff->y_denominator), systif.tif_file_buf+offset+4,4); break; } err = ((int)tag) * (-1); break; /* -- Resolution Unit */ case 0x128 : if( type == _short ){ break; } err = ((int)tag) * (-1); break; /* -- 14. tag 0x131 -- Software */ case 0x131 : if( type == ascii ){ if(offset > 0 && length > 0){ int len; if( tiff->prg ) free( tiff->prg ); len = strlen( (char *)(systif.tif_file_buf+offset) ); tiff->prg = malloc((len+1)*sizeof(char)); strcpy( tiff->prg, (char *)(systif.tif_file_buf+offset) ); } break; } err = ((int)tag) * (-1); break; /* -- 15. tag 0x13B -- Artist */ case 0x13B : if( type == ascii ){ if( offset > 0 && length > 0 ){ int len; if( tiff->au ) free( tiff->au ); len = strlen( (char *)(systif.tif_file_buf+offset) ); tiff->au = malloc((len+1)*sizeof(char)); strcpy( tiff->au, (char *)(systif.tif_file_buf+offset) ); } break; } err = ((int)tag) * (-1); break; /* -- 16. tag 0x140 -- Colormap */ case 0x140 : if( type == _short ){ tiff->offset_color_map = offset; break; } err = ((int)tag) * (-1); break; /* -- 17. tag 0x11C -- Planar Configuration */ case 0x11C : if( type == _short ){ tiff->planar_config = s_offset; break; } err = ((int)tag) * (-1); break; } return(err); } BYTE *read_tif_file_to_buffer( int *tif_err, DWORD *iocount, /*{ */ BYTE *p, char *file ){ BYTE *tif_buffer = p; DWORD file_size=0; BYTE logo[10]; char *ptr_logo = (char*)logo; FILE *fp=NULL; DWORD count; memset(logo,0,10); logo[0]=1; if( *((WORD*)logo) == 1 ) systif.type = 0; /* -- little endian */ else systif.type = 1; /* -- big endian */ if( (fp = fopen(file, "rbu" ) ) == NULL ){ *tif_err = NO_TIF_FILE_FOUND; return( tif_buffer ); } fseek( fp, 0L, SEEK_END ); file_size = ftell(fp); fseek( fp, 0L, SEEK_SET ); if( file_size < 5 ){ *tif_err = NO_TIF_FILE_FORMAT; return( tif_buffer ); } fread((char*)logo,sizeof(BYTE),4,fp); if( strncmp( ptr_logo,"MM",2) != 0 && strncmp( ptr_logo,"II",2) != 0 ){ *tif_err = NO_TIF_FILE_FORMAT; return( tif_buffer ); } if( strncmp( ptr_logo,"II",2) == 0 ){ if( ! ( (logo[2] == '*' ) && (logo[3] == '\0' ) ) ){ *tif_err = NO_TIF_FILE_FORMAT; return( tif_buffer ); } systif.type = systif.type ^ 0; /* -- II and little endian = no swap */ /* -- II and big endian = swap */ } if( strncmp( ptr_logo,"MM",2) == 0 ){ if( ! ( (logo[2] == '\0' ) && (logo[3] == '*' ) ) ){ *tif_err = NO_TIF_FILE_FORMAT; return( tif_buffer ); } systif.type = systif.type ^ 1; /* -- MM and little endian = swap */ /* -- MM and big endian = no swap */ } /* -- allocate buffer of file_size */ tif_buffer = (BYTE *) calloc( file_size+10, sizeof(BYTE) ); if( tif_buffer == (BYTE *)0 ){ fprintf(err_file,"Alloc err in read tiff file (8).\n"); err_val=1; exit(1); } *iocount = fread((char*)(tif_buffer+4),sizeof(BYTE),file_size-4,fp); fclose( fp ); return( tif_buffer ); } void tif_header_debug_long( ttif_par *t ){ int i=0; printf("width,length: %5d, %5d\n",t->image_width,t->image_length ); if( t->bits_per_sample == 0 ){ printf("bits per sample: %5d ",t->rgb_bits_per_sample.r); printf("%d ",t->rgb_bits_per_sample.g); printf("%d \n",t->rgb_bits_per_sample.b); } else printf("bits per sample: %5d \n",t->bits_per_sample); printf("rows per strip: %5d \n",t->rows_per_strip); printf("compression: %5d \n",t->compression); printf("photometric_interpr: %5d \n",t->photometric_interpr); printf("strips per image %5ld \n",t->strips_per_image ); printf("samples per pixel %5d \n",t->samples_per_pixel ); printf("offset strips %8lu \n",t->offset_strips ); printf("offset colormap %8u \n",t->offset_color_map); printf("planar configuration %5u\n", t->planar_config ); printf("x resolution %5d.%d\n",t->x_numerator,t->x_denominator); printf("y resolution %5d.%d\n",t->y_numerator,t->y_denominator); printf("resolution unit %5d\n",t->resolution_unit); if( t->au ) printf("autor : %s\n",t->au ); else printf("autor : %s\n","not used" ); if( t->prg ) printf("prg : %s\n",t->prg ); else printf("prg : %s\n","not used" ); if( t->doc ) printf("Document : %s\n",t->doc ); else printf("Document : %s\n","not used" ); if( t->name ) printf("Image Descr : %s\n",t->name ); else printf("Image Descr : %s\n","not used" ); if( t->make ) printf("Make : %s\n",t->make ); else printf("Make : %s\n","not used" ); if( t->model ) printf("Model : %s\n",t->model ); else printf("Model : %s\n","not used" ); } void tif_header_debug( ttif_par *t ){ int i=0; printf("TIFF: width: %3d, length: %3d\n",t->image_width,t->image_length ); if( t->photometric_interpr == 0 ) printf("Gray level image\n"); if( t->photometric_interpr == 1 ) printf("Gray level image\n"); if( t->photometric_interpr == 2 ) printf("24-bit image\n"); if( t->photometric_interpr == 3 ) printf("Colormap image\n"); if( t->au ) printf("autor : %s\n",t->au ); else printf("autor : %s\n","not used" ); if( t->prg ) printf("prg : %s\n",t->prg ); else printf("prg : %s\n","not used" ); if( t->name ) printf("Descr : %s\n",t->name ); else printf("Descr : %s\n","not used" ); if( t->doc ) printf("Document : %s\n",t->doc ); else printf("Document : %s\n","not used" ); if( t->make ) printf("Make : %s\n",t->make ); else printf("Make : %s\n","not used" ); if( t->model ) printf("Model : %s\n",t->model ); else printf("Model : %s\n","not used" ); printf("\n"); } int g_read_tiff( BYTE **buf, BYTE **r, BYTE **g, BYTE **b, BYTE **lut, char *file_name, int nr){ ttif_par *tiff = &(systif.tif_par); /* -- global */ DWORD i; DWORD offset; WORD entry_count; BYTE *t_buffer = NULL; int err=0; DWORD iocount; char name[280]; strcpy( name, file_name ); if( strchr(name,'.') == NULL ){ sprintf(name,"%s.%03d",name,nr); } t_buffer = read_tif_file_to_buffer( &err, &iocount, t_buffer, name ); if( t_buffer == NULL ){ if( err == NO_TIF_FILE_FOUND ) fprintf(err_file," TIFF File '%s' not found.\n",name); if( err == NO_TIF_FILE_FORMAT ){ fprintf(err_file," File '%s' is not a TIFF File.\n",name); } err_val=err; return -1; } /* -- in t_buffer is the TIFF-File, copy ptr to global and free the pointers */ if( *buf ) /* -- gray channel */ free(*buf); *buf = NULL; if( *r ) /* -- red channel */ free(*r); *r = NULL; if( *g ) /* -- green channel */ free( *g ); *g = NULL; if( *b ) /* -- blue channel */ free(*b); *b = NULL; systif.tif_file_buf = t_buffer; /* -- first dir */ memcpy( &offset, t_buffer + TIFF_LONG_SIZE, TIFF_LONG_SIZE ); if( systif.type == 1 ) gtif_DWORD_swab( &offset ); memcpy( &entry_count, t_buffer+offset, TIFF_SHORT_SIZE ); if( systif.type == 1 ) gtif_WORD_swab( &entry_count ); systif.p_tif_dir = (ttif_dir *)(t_buffer+offset+TIFF_SHORT_SIZE ); tiff->rows_per_strip = 0; tiff->samples_per_pixel = 1; for(i=0; i< entry_count; i++){ ttif_dir entry; BYTE *p; p = ((BYTE*)systif.p_tif_dir) + i * TIFF_DIR_ENTRY_SIZE; memcpy( &entry.tag, p + TIFF_TAG_OFFSET, TIFF_SHORT_SIZE ); memcpy( &entry.type, p + TIFF_TYPE_OFFSET, TIFF_SHORT_SIZE ); memcpy( &entry.length, p + TIFF_LENGTH_OFFSET, TIFF_LONG_SIZE ); memcpy( &entry.offset, p + TIFF_OFFSET_OFFSET, TIFF_LONG_SIZE ); if( g_scan_tif_entry( &entry ) ){ fprintf(err_file, "Err in tag entry: %02X\n",i ); err_val = 5; return -1; } } #ifndef MS_DOS_USED if( tiff_info_toggle ) tif_header_debug( tiff ); #endif /* tif_header_debug_long( tiff ); fflush(stdin); i=getchar(); */ if( (tiff->rows_per_strip == 0 || tiff->rows_per_strip == -1) && tiff->strips_per_image == 1 ) tiff->rows_per_strip = tiff->image_length; /* -- 8 bit images */ if( tiff->photometric_interpr == 1 || tiff->photometric_interpr == 3 ){ /* -- allocate gray channel */ *buf = (unsigned char *)malloc( tiff->image_length*(tiff->image_width) *sizeof(unsigned char) ); if( *buf == NULL ){ fprintf(err_file,"Allocation err in 'g_im_tiff_read'\n"); err_val = 6; return -1; } if( (tiff->bits_per_sample == 8 ) && tiff->samples_per_pixel == 1 ){ copy_to_BYTE_array( *buf ); /* -- Convert Color Map imgs */ if( tiff->photometric_interpr == 3 ){ unsigned char *l = *lut; unsigned long ic=0; WORD *wbuf=malloc(256*3*sizeof(WORD)); memcpy( wbuf, t_buffer + tiff->offset_color_map, 256*3*sizeof(WORD) ); for( ic=0;ic<256;ic++){ *(l+3*ic+0) = (unsigned char)(*(wbuf+ic) >> 8); *(l+3*ic+1) = (unsigned char)(*(wbuf+256+ic) >> 8 ); *(l+3*ic+2) = (unsigned char)(*(wbuf+2*256+ic) >> 8 ); } free(wbuf); } } else{ fprintf(err_file,"unknown tiff file type 'g_im_tiff_read'\n"); err_val = 7; iocount = 0xffffffff; } } /* -- 24 bit images */ if( tiff->photometric_interpr == 2 ){ unsigned char *ptr_image; int ii; /* -- allocate red channel */ *r = (unsigned char *)calloc( tiff->image_length*(tiff->image_width), sizeof(unsigned char) ); if( *r == NULL ){ fprintf(err_file,"Allocation err in 'g_im_tiff_read' red ch.\n"); err_val = 6; return -1; } /* -- allocate blue channel */ *b = (unsigned char *)calloc( tiff->image_length*(tiff->image_width), sizeof(unsigned char) ); if( *b == NULL ){ fprintf(err_file,"Allocation err in 'g_im_tiff_read' blue ch.\n"); err_val = 6; return -1; } /* -- allocate green channel */ *g = (unsigned char *)calloc( tiff->image_length*(tiff->image_width), sizeof(unsigned char) ); if( *g == NULL ){ fprintf(err_file,"Allocation err in 'g_im_tiff_read' green ch.\n"); err_val = 6; return -1; } switch( tiff->planar_config ){ case 1: if( tiff->strips_per_image == 1 ){ ptr_image = systif.tif_file_buf + tiff->offset_strips; for( ii=0;ii < tiff->image_width * tiff->image_length; ii++){ *(*r + ii ) = *(ptr_image+3*ii+0) ; *(*g + ii ) = *(ptr_image+3*ii+1) ; *(*b + ii ) = *(ptr_image+3*ii+2) ; } } else{ DWORD bytes_per_strip = tiff->rows_per_strip * tiff->image_width; DWORD offset_faktor; DWORD offset; BYTE *poff; BYTE *pr = *r; BYTE *pg = *g; BYTE *pb = *b; DWORD i; DWORD last_count; if( tiff->long_offset ) offset_faktor = 4; else offset_faktor = 2; poff = ( systif.tif_file_buf + tiff->offset_strips ); for( i=0; i < ( tiff->strips_per_image-1 ); i++ ){ if( tiff->long_offset ){ memcpy( &offset, poff, sizeof( DWORD )); } else{ WORD a; memcpy( &a, poff, sizeof( WORD )); offset = a; } ptr_image = systif.tif_file_buf + offset; for( ii=0;ii < bytes_per_strip; ii++){ *(pr++ ) = *(ptr_image+3*ii+0) ; *(pg++ ) = *(ptr_image+3*ii+1) ; *(pb++ ) = *(ptr_image+3*ii+2) ; } poff += offset_faktor; } /* -- last strip -- last count = img_size - read_size */ last_count = (tiff->image_width * tiff->image_length ) - ( bytes_per_strip * (tiff->strips_per_image-1)); if( tiff->long_offset ){ memcpy( &offset, poff, sizeof( DWORD )); } else{ WORD a; memcpy( &a, poff, sizeof( WORD )); offset = (DWORD)a; } ptr_image = systif.tif_file_buf + offset; for( ii=0;ii < last_count; ii++){ *(pr++ ) = *(ptr_image+3*ii+0) ; *(pg++ ) = *(ptr_image+3*ii+1) ; *(pb++ ) = *(ptr_image+3*ii+2) ; } poff += offset_faktor; } break; case 2: if( tiff->strips_per_image == 3 ){ DWORD offset; DWORD a; if( tiff->long_offset == 1 ){ memcpy(&a, systif.tif_file_buf + tiff->offset_strips,4 ); offset = a; } else{ memcpy(&a, systif.tif_file_buf + tiff->offset_strips,2 ); offset = (WORD)a; } ptr_image = systif.tif_file_buf + offset; memcpy( *r, ptr_image, tiff->image_width * tiff->image_length); if( tiff->long_offset == 1 ){ memcpy(&a, systif.tif_file_buf + tiff->offset_strips+4,4 ); offset = a; } else{ memcpy(&a, systif.tif_file_buf + tiff->offset_strips+2,2 ); offset = (WORD)a; } ptr_image = systif.tif_file_buf + offset; memcpy( *g, ptr_image, tiff->image_width * tiff->image_length); if( tiff->long_offset == 1 ){ memcpy(&a, systif.tif_file_buf + tiff->offset_strips + 8, 4 ); offset = a; } else{ memcpy(&a, systif.tif_file_buf + tiff->offset_strips+4,2 ); offset = (WORD)a; } ptr_image = systif.tif_file_buf + offset; memcpy( *b, ptr_image, tiff->image_width * tiff->image_length); break; } else{ fprintf(err_file,"unknown tiff file type 'g_im_tiff_read'\n"); fprintf(err_file,"24 bit image, strips per image != 3\n"); err_val=7; iocount = 0xffffffff; break; } default: fprintf(err_file,"unknown tiff file type 'g_im_tiff_read'\n"); err_val = 7; iocount = 0xffffffff; } } if( t_buffer ) free( t_buffer ); t_buffer = NULL; systif.p_tif_dir = NULL; systif.tif_file_buf = NULL; return( iocount ); } static int tiff_init( ){ systif.p_tif_dir = NULL; systif.tif_file_buf = NULL; systif.data_size = 0; systif.entry_count = 0; systif.tif_par.image_width = 0; systif.tif_par.image_length = 0; systif.tif_par.bits_per_sample = 0; systif.tif_par.rgb_bits_per_sample.r = 0; systif.tif_par.rgb_bits_per_sample.g = 0; systif.tif_par.rgb_bits_per_sample.b = 0; systif.tif_par.compression = 0; systif.tif_par.photometric_interpr = 0; systif.tif_par.offset_color_map = 0; systif.tif_par.doc = NULL; systif.tif_par.name = NULL; systif.tif_par.make = NULL; systif.tif_par.model = NULL; systif.tif_par.au = NULL; systif.tif_par.prg = NULL; systif.tif_par.date = NULL; systif.tif_par.strips_per_image = 0; systif.tif_par.rows_per_strip = 0; systif.tif_par.offset_strips = 0; systif.tif_par.offset_counts = 0; systif.tif_par.strip_byte_counts = 0; systif.tif_par.long_offset = 0; systif.tif_par.samples_per_pixel = 0; systif.tif_par.x_numerator = 0; systif.tif_par.x_denominator = 0; systif.tif_par.y_numerator = 0; systif.tif_par.y_denominator = 0; systif.tif_par.planar_config = 0; systif.tif_par.resolution_unit = 0; return 0; } static int tiff_free( ){ systif.p_tif_dir = NULL; systif.tif_file_buf = NULL; if( systif.tif_par.doc != NULL ) free( systif.tif_par.doc ), systif.tif_par.doc = NULL; if( systif.tif_par.name != NULL ) free( systif.tif_par.name ), systif.tif_par.name = NULL; if( systif.tif_par.make != NULL ) free( systif.tif_par.make ), systif.tif_par.make = NULL; if( systif.tif_par.model != NULL ) free( systif.tif_par.model ), systif.tif_par.model = NULL; if( systif.tif_par.au != NULL ) free( systif.tif_par.au ), systif.tif_par.au = NULL; if( systif.tif_par.prg != NULL ) free( systif.tif_par.prg ), systif.tif_par.prg = NULL; if( systif.tif_par.date != NULL ) free( systif.tif_par.date ), systif.tif_par.date = NULL; return 0; } int std_tiff_free( ){ return( tiff_free()); } int g_im_read_tiff( g_im *p, char *name, int nr){ ttif_par *tiff = &(systif.tif_par); /* -- global */ int ret = 0; tiff_init( ); ret = g_read_tiff( &(p->buf), &(p->r), &(p->g), &(p->b), &(p->lut), name, nr ); /* -- update g_im */ p->size.x = tiff->image_width; p->size.y = tiff->image_length; p->x_resolution = ((double)tiff->x_numerator) + ((double)tiff->x_denominator / 10000.0 ); p->y_resolution = ((double)tiff->y_numerator) + ((double)tiff->y_denominator / 10000.0 ); if( tiff->au ){ *(tiff->au + 39) = 0; strcpy(p->au,tiff->au); } if( tiff->prg ){ *(tiff->prg + 39) = 0; strcpy(p->prg,tiff->prg); } /* -- first is gray level tiff */ if( tiff->bits_per_sample == 8 && tiff->samples_per_pixel == 1 ){ p->type = G_IM_GRAY; } /* -- Colormap Tiff */ if( tiff->photometric_interpr == 3 ){ p->type = G_IM_PAL; } /* -- RGB tiff */ if( tiff->photometric_interpr == 2 ){ p->type = G_IM_RGB; } tiff_free( ); return ret; } #ifdef MS_DOS_USED int g_im_read_tiff_host_8( g_im *p, char *name, int nr){ return( g_im_read_tiff( p, name, nr)); } #endif #ifndef MS_DOS_USED g_im *g_alloc( int x, int y ){ g_im *p=calloc(1,sizeof(g_im)); if( p == (g_im *)0 ){ fprintf( err_file," Null Pointer in g_alloc, 'g_im' structure \n"); return p; } if( x > 0 && y > 0 ){ p->buf=(BYTE *)calloc((unsigned )(y*x),sizeof(BYTE)); if(p->buf == (BYTE *)0 ){ fprintf( err_file," Null Pointer in g_alloc, 'img' area \n"); p = g_free( p ); p = (g_im*)0; return p; } } p->wbuf=0; p->dbuf=0; p->r=p->g=p->b=0; p->size.x=x; p->size.y=y; p->start.x=0; p->start.y=0; p->end.x=x; p->end.y=y; p->x_resolution = 2.8; p->y_resolution = 2.8; strcpy(p->name,""); strcpy(p->au,"R. Albrecht, MPI f. Biochemie"); strcpy(p->prg,"DEC ULTRIX, Image Prozessor"); strcpy(p->date,"not avail"); p->type=G_IM_GRAY; /* -- normal grayscale img */ p->lut=(BYTE*)calloc(GR_LUT_SIZE,sizeof(BYTE)); p->target = 0; /* -- set default display */ return p; } g_im *g_free( g_im *p ){ if( p ){ if( p->buf ) free(p->buf); if( p->wbuf ) free(p->wbuf); if( p->dbuf ) free(p->dbuf); if( p->r ) free(p->r); if( p->g ) free(p->g); if( p->b ) free(p->b); if(p->lut) free(p->lut); free(p); p = (g_im *)0; } return p; } #endif