📄 dim_tiff_format_io.cpp
字号:
/*****************************************************************************
TIFF IO
Copyright (c) 2004 by Dmitry V. Fedorov <www.dimin.net> <dima@dimin.net>
IMPLEMENTATION
Programmer: Dima V. Fedorov <mailto:dima@dimin.net> <http://www.dimin.net/>
TODO:
4) read preview image in RGB 8bit
History:
03/29/2004 22:23 - First creation
Ver : 1
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "memio.h"
#include "dim_tiny_tiff.h"
#include "dim_tiff_format.h"
int invertSample(TDimImageBitmap *img, int sample);
int invertImg(TDimImageBitmap *img);
// must include these guys here if not no access to internal TIFF structs
#include "dim_tiny_tiff.cpp"
#include "dim_stk_format_io.cpp"
#include "dim_psia_format_io.cpp"
#include "dim_fluoview_format_io.cpp"
//****************************************************************************
// util procs
//****************************************************************************
int invertSample(TDimImageBitmap *img, int sample)
{
if (img == 0) return -1;
int i;
long size = img->i.width * img->i.height;
DIM_UINT max_uint16 = (DIM_UINT16) -1;
DIM_UINT max_uchar = (DIM_UCHAR) -1;
if (img->i.depth == 16)
{
uint16 *p = (uint16 *) img->bits[sample];
for (i=0; i<size; i++) {
*p = max_uint16 - *p;
p++;
}
}
if (img->i.depth == 8) // 8bit
{
DIM_UCHAR *p = (DIM_UCHAR *) img->bits[sample];
for (i=0; i<size; i++) {
*p = max_uchar - *p;
p++;
}
}
return 0;
}
int invertImg(TDimImageBitmap *img)
{
if (img == 0) return -1;
DIM_UINT sample;
for (sample=0; sample<img->i.samples; sample++)
{
invertSample(img, sample);
}
return 0;
}
//****************************************************************************
// *FILE handlers
//****************************************************************************
/*
static tsize_t tiff_read(thandle_t handle,tdata_t data,tsize_t size)
{
FILE *stream = (FILE*) handle;
return (tsize_t) fread(data, sizeof(unsigned char), size, stream);
}
static tsize_t tiff_write(thandle_t handle,tdata_t data,tsize_t size)
{
FILE *stream = (FILE*) handle;
return (tsize_t) fwrite(data, sizeof(unsigned char), size, stream);
}
static toff_t tiff_seek(thandle_t handle, toff_t offset, int whence)
{
FILE *stream = (FILE*) handle;
if ( fseek( stream, offset, whence ) == 0)
return ftell( stream );
else
return 0;
}
static int tiff_close(thandle_t handle)
{
FILE *stream = (FILE*) handle;
fflush( stream );
fclose( stream );
return 0;
}
static toff_t tiff_size(thandle_t handle)
{
uint size, cur_pos;
FILE *stream = (FILE*) handle;
cur_pos = ftell( stream );
fseek( stream, 0, SEEK_END );
size = ftell( stream );
fseek( stream, cur_pos, SEEK_SET );
return size;
}
static int tiff_mmap(thandle_t handle,tdata_t* data,toff_t* size)
{
handle=handle; data=data; size=size;
return (int) MAP_FAILED;
}
static void tiff_unmap(thandle_t handle, tdata_t data, toff_t size)
{
handle=handle; data=data; size=size;
}
*/
//****************************************************************************
// MISC
//****************************************************************************
bool areValidParams(TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams)
{
if (fmtHndl == NULL) return FALSE;
if (tifParams == NULL) return FALSE;
if (tifParams->dimTiff == NULL) return FALSE;
if (fmtHndl->image == NULL) return FALSE;
return TRUE;
}
void init_image_palette( TIFF *tif, TDimImageInfo *info )
{
DIM_UINT i;
uint16 photometric = PHOTOMETRIC_MINISWHITE;
uint16 bitspersample = 1;
if (tif == NULL) return;
if (info == NULL) return;
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
info->lut.count = 0;
for (i=0; i<256; i++) info->lut.rgba[i] = i*256;
if (photometric == PHOTOMETRIC_PALETTE)
{ // palette
uint16 *red;
uint16 *green;
uint16 *blue;
DIM_UINT num_colors = ( 1<<bitspersample );
if (num_colors > 256) num_colors = 256;
TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);
for (i=0; i<num_colors; i++)
{
info->lut.rgba[i] = dimRGB( red[i]/256, green[i]/256, blue[i]/256 );
} // for colors
info->lut.count = num_colors;
} // if paletted
}
//****************************************************************************
// META DATA
//****************************************************************************
DIM_UINT read_one_tag (TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams, int tag)
{
if (!areValidParams(fmtHndl, tifParams)) return 1;
if (tifParams->ifds.count == 0) return 1;
if (fmtHndl->pageNumber >= tifParams->ifds.count) fmtHndl->pageNumber = 0;
TIFF *tif = tifParams->dimTiff;
TDimTiffIFDs *ifds = &tifParams->ifds;
DIM_UCHAR *buf = NULL;
uint32 buf_size;
uint32 buf_type;
if ( (tifParams->subType == tstStk) && (tag == 33629) ) // stk 33629 got custom size 6*N
{
buf_type = DIM_TAG_LONG;
DIM_INT32 count = getTiffTagCount(tif, &ifds->ifds[fmtHndl->pageNumber], tag);
buf_size = ( count * 6 ) * tag_size_bytes[buf_type];
readTiffCustomTag (tif, &ifds->ifds[fmtHndl->pageNumber], tag, buf_size, buf_type, (DIM_UCHAR **) &buf);
}
else
readTiffTag (tif, &ifds->ifds[fmtHndl->pageNumber], tag, buf_size, buf_type, (DIM_UCHAR **) &buf);
if ( (buf_size == 0) || (buf == NULL) ) return 1;
else
{
// now add tag into structure
TDimTagItem item;
item.tagGroup = DIM_META_TIFF_TAG;
item.tagId = tag;
item.tagType = buf_type;
item.tagLength = buf_size / tag_size_bytes[buf_type];
item.tagData = buf;
addMetaTag( &fmtHndl->metaData, item);
}
return 0;
}
DIM_UINT read_tiff_metadata (TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams, int group, int tag, int type)
{
if (!areValidParams(fmtHndl, tifParams)) return 1;
if (group == DIM_META_BIORAD) return 1;
if (fmtHndl->pageNumber >= tifParams->ifds.count) fmtHndl->pageNumber = 0;
// first read custom formatted tags
if (tifParams->subType == tstStk)
stkReadMetaMeta (fmtHndl, group, tag, type);
if (tag != -1)
return read_one_tag ( fmtHndl, tifParams, tag );
if ( (group == -1) || (group == DIM_META_TIFF_TAG) )
{
DIM_UINT i;
TDimTiffIFD *ifd = &tifParams->ifds.ifds[fmtHndl->pageNumber];
for (i=0; i<ifd->count; i++ )
{
if (type == -1)
{
if ( (ifd->entries[i].tag > 532) &&
(ifd->entries[i].tag != 50434)
) read_one_tag ( fmtHndl, tifParams, ifd->entries[i].tag );
switch( ifd->entries[i].tag )
{
case 269: //DocumentName
case 270: //ImageDescription
case 271: //Make
case 272: //Model
case 285: //PageName
case 305: //Software
case 306: //DateTime
case 315: //Artist
case 316: //HostComputer
read_one_tag ( fmtHndl, tifParams, ifd->entries[i].tag );
break;
} // switch
} // type == -1
else
{
if (ifd->entries[i].type == type)
read_one_tag ( fmtHndl, tifParams, ifd->entries[i].tag );
} // type != -1
} // for i<ifd count
} // if no group
return 0;
}
void change_0_to_n (char *str, long size)
{
long i;
for (i=0; i<size; i++)
{
if (str[i] == '\0') str[i] = '\n';
}
}
void write_title_text(const char *text, MemIOBuf *outIOBuf)
{
char title[1024];
sprintf(title, "\n[%s]\n\n", text);
MemIO_WriteProc( (thandle_t) outIOBuf, title, strlen(title)-1 );
}
void read_text_tag(TIFF *tif, TDimTiffIFD *ifd, DIM_UINT tag, MemIOBuf *outIOBuf, const char *text)
{
uint32 buf_size;
uint32 buf_type;
DIM_UCHAR *buf = NULL;
if (isTagPresentInIFD ( ifd, tag ) == TRUE )
{
write_title_text(text, outIOBuf);
readTiffTag (tif, ifd, tag, buf_size, buf_type, &buf);
change_0_to_n ((char *) buf, buf_size);
MemIO_WriteProc( (thandle_t) outIOBuf, buf, buf_size );
freeTiffTagBuf( (DIM_UCHAR **) &buf );
}
}
void read_text_tag(TIFF *tif, TDimTiffIFD *ifd, DIM_UINT tag, MemIOBuf *outIOBuf)
{
uint32 buf_size;
uint32 buf_type;
DIM_UCHAR *buf = NULL;
if (isTagPresentInIFD ( ifd, tag ) == TRUE )
{
readTiffTag (tif, ifd, tag, buf_size, buf_type, &buf);
change_0_to_n ((char *) buf, buf_size);
MemIO_WriteProc( (thandle_t) outIOBuf, buf, buf_size );
freeTiffTagBuf( (DIM_UCHAR **) &buf );
}
}
char* read_text_tiff_metadata ( TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams )
{
TIFF *tif = tifParams->dimTiff;
TDimTiffIFD *ifd = &tifParams->ifds.ifds[0];
MemIOBuf outIOBuf;
char *str = NULL;
MemIO_InitBuf( &outIOBuf, 0, NULL );
//-------------------------------------------------------------------------------
// Some internal meta data
//-------------------------------------------------------------------------------
write_title_text("Internal Metadata", &outIOBuf);
if (tifParams->subType == tstStk)
stkWriteTextMeta(tifParams, &outIOBuf);
if (tifParams->subType == tstPsia)
psiaWriteTextMeta(tifParams, &outIOBuf);
if (tifParams->subType == tstFluoview)
fluoviewWriteTextMeta(tifParams, &outIOBuf);
//-------------------------------------------------------------------------------
// Standard TIFF tags
//-------------------------------------------------------------------------------
//DocumentName
read_text_tag(tif, ifd, 269, &outIOBuf, "Document Name");
//ImageDescription
if (tifParams->subType == tstStk)
{
uint32 buf_size;
uint32 buf_type;
if (isTagPresentInIFD ( ifd, 270 ) == TRUE )
{
DIM_UCHAR *buf = NULL;
write_title_text("Image Description", &outIOBuf);
readTiffTag (tif, ifd, 270, buf_size, buf_type, (DIM_UCHAR **) &buf);
MemIO_WriteProc( (thandle_t) &outIOBuf, buf, strlen((char *) buf)-1 );
freeTiffTagBuf( (DIM_UCHAR **) &buf );
}
}
else
if (tifParams->subType != tstFluoview)
read_text_tag(tif, ifd, 270, &outIOBuf, "Image Description");
//PageName
if (tifParams->subType != tstFluoview)
read_text_tag(tif, ifd, 285, &outIOBuf, "Page Name");
//Make
read_text_tag(tif, ifd, 271, &outIOBuf, "Make");
//Model
read_text_tag(tif, ifd, 272, &outIOBuf, "Model");
//Software
read_text_tag(tif, ifd, 305, &outIOBuf, "Software");
//DateTime
read_text_tag(tif, ifd, 306, &outIOBuf, "Date Time");
//Artist
read_text_tag(tif, ifd, 315, &outIOBuf, "Artist");
//HostComputer
read_text_tag(tif, ifd, 316, &outIOBuf, "Host Computer");
str = new char [outIOBuf.size+1];
str[outIOBuf.size] = '\0';
memcpy( str, outIOBuf.data, outIOBuf.size );
MemIO_DeinitBuf( &outIOBuf );
return str;
}
DIM_UINT write_tiff_metadata (TDimFormatHandle *fmtHndl, TDimTiffParams *tifParams)
{
if (!areValidParams(fmtHndl, tifParams)) return 1;
DIM_UINT i;
TDimTagList *tagList = &fmtHndl->metaData;
void *t_list = NULL;
int16 t_list_count;
TIFF *tif = tifParams->dimTiff;
if (tagList->count == 0) return 1;
if (tagList->tags == NULL) return 1;
for (i=0; i<tagList->count; i++)
{
TDimTagItem *tagItem = &tagList->tags[i];
if (tagItem->tagGroup == DIM_META_TIFF_TAG)
{
t_list = tagItem->tagData;
t_list_count = tagItem->tagLength;
TIFFSetField( tif, tagItem->tagId, tagItem->tagLength, tagItem->tagData );
}
}
return 0;
}
//****************************************************************************
// WRITING LINE SEGMENT FROM BUFFER
//****************************************************************************
void write_line_segment_8(void *po, void *bufo, TDimImageBitmap *img, DIM_UINT sample, DIM_ULONG w)
{
DIM_UCHAR *p = (DIM_UCHAR *) po;
DIM_UCHAR *buf = (DIM_UCHAR *) bufo;
DIM_UINT nsamples = img->i.samples;
register DIM_UINT x, xi=0;
for (x=sample; x<w*nsamples; x+=nsamples)
{
p[xi] = buf[x];
xi++;
}
}
void write_line_segment_16(void *po, void *bufo, TDimImageBitmap *img, DIM_UINT sample, DIM_ULONG w)
{
DIM_UINT16 *p = (DIM_UINT16 *) po;
DIM_UINT16 *buf = (DIM_UINT16 *) bufo;
DIM_UINT nsamples = img->i.samples;
register DIM_UINT x, xi=0;
for (x=sample; x<w*nsamples; x+=nsamples)
{
p[xi] = buf[x];
xi++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -