2002-08-18 Oliver Rauch <Oliver.Rauch@rauch-domain.de>

* frontend/scanimage.c, frontend/stiff.h, frontend/stiff.c:
          Added option "-i filename"/"--icc-profile filename":
          When image is saved in tiff format then this icc-profile is
          added to the tiff file as tiff tag
DEVEL_2_0_BRANCH-1
Oliver Rauch 2002-08-27 17:57:19 +00:00
rodzic 2b54c3e7c4
commit d054ded6c1
3 zmienionych plików z 118 dodań i 10 usunięć

Wyświetl plik

@ -88,13 +88,14 @@ static struct option basic_options[] = {
{"batch-increment", required_argument, NULL, OPTION_BATCH_INCREMENT},
{"format", required_argument, NULL, OPTION_FORMAT},
{"accept-md5-only", no_argument, NULL, OPTION_MD5},
{"icc-profile", required_argument, NULL, 'i'},
{0, 0, NULL, 0}
};
#define OUTPUT_PNM 0
#define OUTPUT_TIFF 1
#define BASE_OPTSTRING "d:hLf:vVTb"
#define BASE_OPTSTRING "d:hi:Lf:vVTb"
#define STRIP_HEIGHT 256 /* # lines we increment image height */
static struct option *all_options;
@ -112,6 +113,7 @@ static int resolution_optind = -1, resolution_value = 0;
static SANE_Word window_val[2];
static int window_val_user[2]; /* is width/height user-specified? */
static int accept_only_md5_auth = 0;
static const char *icc_profile = NULL;
static void fetch_options (SANE_Device * device);
static void scanimage_exit (void);
@ -1079,7 +1081,7 @@ scan_it (void)
if (output_format == OUTPUT_TIFF)
sanei_write_tiff_header (parm.format,
parm.pixels_per_line, parm.lines,
parm.depth, resolution_value);
parm.depth, resolution_value, icc_profile);
else
write_pnm_header (parm.format, parm.pixels_per_line,
parm.lines, parm.depth);
@ -1246,7 +1248,7 @@ scan_it (void)
image.height = image.y;
if (output_format == OUTPUT_TIFF)
sanei_write_tiff_header (parm.format, parm.pixels_per_line,
parm.lines, parm.depth, resolution_value);
parm.lines, parm.depth, resolution_value, icc_profile);
else
write_pnm_header (parm.format, image.width, image.height, parm.depth);
if ((output_format == OUTPUT_TIFF) || (image.Bpp == 1)
@ -1495,6 +1497,9 @@ main (int argc, char **argv)
case 'h':
help = 1;
break;
case 'i': /* icc profile */
icc_profile = optarg;
break;
case 'v':
++verbose;
break;
@ -1676,7 +1681,8 @@ standard output.\n\
-T, --test test backend thoroughly\n\
-v, --verbose give even more status messages\n\
-V, --version print version information\n\
--accept-md5-only only accept authorization requests using md5\n", prog_name);
--accept-md5-only only accept authorization requests using md5\n\
-i, --icc-profile=PROFILE include this ICC profile into TIFF file\n", prog_name);
if (!devname)
{

Wyświetl plik

@ -1,5 +1,6 @@
/* Create SANE/tiff headers TIFF interfacing routines for SANE
Copyright (C) 2000 Peter Kirchgessner
Copyright (C) 2002 Oliver Rauch: added tiff ICC profile
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@ -18,6 +19,7 @@
/* Changes:
2000-11-19, PK: Color TIFF-header: write 3 values for bits per sample
2001-12-16, PK: Write fill order tag for b/w-images
2002-08-27, OR: Added tiff tag for ICC profile
*/
#ifdef _AIX
# include "../include/lalloca.h" /* MUST come first for AIX! */
@ -260,13 +262,30 @@ write_tiff_bw_header (FILE *fptr, int width, int height, int resolution)
static void
write_tiff_grey_header (FILE *fptr, int width, int height, int depth,
int resolution)
int resolution, const char *icc_profile)
{IFD *ifd;
int header_size = 8, ifd_size;
int strip_offset, data_offset, data_size;
int strip_bytecount;
int ntags;
int motorola, bps, maxsamplevalue;
FILE *icc_file = 0;
int icc_len = -1;
if (icc_profile)
{
icc_file = fopen(icc_profile, "r");
if (!icc_file)
{
fprintf(stderr, "Could not open ICC profile %s\n", icc_profile);
}
else
{
icc_len = 16777216 * fgetc(icc_file)*65536+fgetc(icc_file)+fgetc(icc_file)*256+fgetc(icc_file);
rewind(icc_file);
}
}
ifd = create_ifd ();
@ -283,6 +302,12 @@ write_tiff_grey_header (FILE *fptr, int width, int height, int depth,
data_size += 2*4 + 2*4;
}
if (icc_len > 0) /* if icc profile exists add memory for tag */
{
ntags += 1;
data_size += icc_len;
}
ifd_size = 2 + ntags*12 + 4;
data_offset = header_size + ifd_size;
strip_offset = data_offset + data_size;
@ -330,6 +355,12 @@ write_tiff_grey_header (FILE *fptr, int width, int height, int depth,
add_ifd_entry (ifd, 296, IFDE_TYP_SHORT, 1, 2);
}
if (icc_len > 0) /* add ICC-profile TAG */
{
add_ifd_entry(ifd, 34675, 7, icc_len, data_offset);
data_offset += icc_len;
}
/* I prefer motorola format. Its human readable. But for 16 bit, */
/* the image format is defined by SANE to be the native byte order */
if (bps == 1)
@ -352,19 +383,55 @@ write_tiff_grey_header (FILE *fptr, int width, int height, int depth,
write_i4 (fptr, 1, motorola);
}
/* Write ICC profile */
if (icc_len > 0)
{
int i;
for (i=0; i<icc_len; i++)
{
if (!feof(icc_file))
{
fputc(fgetc(icc_file), fptr);
}
else
{
fprintf(stderr, "ICC profile %s is too short\n", icc_profile);
break;
}
}
}
free_ifd (ifd);
}
static void
write_tiff_color_header (FILE *fptr, int width, int height, int depth,
int resolution)
int resolution, const char *icc_profile)
{IFD *ifd;
int header_size = 8, ifd_size;
int strip_offset, data_offset, data_size;
int strip_bytecount;
int ntags;
int motorola, bps, maxsamplevalue;
FILE *icc_file = 0;
int icc_len = -1;
if (icc_profile)
{
icc_file = fopen(icc_profile, "r");
if (!icc_file)
{
fprintf(stderr, "Could not open ICC profile %s\n", icc_profile);
}
else
{
icc_len = 16777216 * fgetc(icc_file)*65536+fgetc(icc_file)+fgetc(icc_file)*256+fgetc(icc_file);
rewind(icc_file);
}
}
ifd = create_ifd ();
@ -375,12 +442,20 @@ write_tiff_color_header (FILE *fptr, int width, int height, int depth,
/* the following values must be known in advance */
ntags = 13;
data_size = 3*2 + 3*2 + 3*2;
if (resolution > 0)
{
ntags += 3;
data_size += 2*4 + 2*4;
}
if (icc_len > 0) /* if icc profile exists add memory for tag */
{
ntags += 1;
data_size += icc_len;
}
ifd_size = 2 + ntags*12 + 4;
data_offset = header_size + ifd_size;
strip_offset = data_offset + data_size;
@ -416,6 +491,7 @@ write_tiff_color_header (FILE *fptr, int width, int height, int depth,
/* max sample value */
add_ifd_entry (ifd, 281, IFDE_TYP_SHORT, 3, data_offset);
data_offset += 3*2;
if (resolution > 0)
{
/* x resolution */
@ -425,12 +501,20 @@ write_tiff_color_header (FILE *fptr, int width, int height, int depth,
add_ifd_entry (ifd, 283, IFDE_TYP_RATIONAL, 1, data_offset);
data_offset += 2*4;
}
if (resolution > 0)
{
/* resolution unit (dpi) */
add_ifd_entry (ifd, 296, IFDE_TYP_SHORT, 1, 2);
}
if (icc_len > 0) /* add ICC-profile TAG */
{
add_ifd_entry(ifd, 34675, 7, icc_len, data_offset);
data_offset += icc_len;
}
/* I prefer motorola format. Its human readable. But for 16 bit, */
/* the image format is defined by SANE to be the native byte order */
if (bps == 1)
@ -468,13 +552,31 @@ write_tiff_color_header (FILE *fptr, int width, int height, int depth,
write_i4 (fptr, 1, motorola);
}
/* Write ICC profile */
if (icc_len > 0)
{
int i;
for (i=0; i<icc_len; i++)
{
if (!feof(icc_file))
{
fputc(fgetc(icc_file), fptr);
}
else
{
fprintf(stderr, "ICC profile %s is too short\n", icc_profile);
break;
}
}
}
free_ifd (ifd);
}
void
sanei_write_tiff_header (SANE_Frame format, int width, int height, int depth,
int resolution)
int resolution, const char *icc_profile)
{
#ifdef __EMX__ /* OS2 - write in binary mode. */
_fsetmode(stdout, "b");
@ -485,14 +587,14 @@ sanei_write_tiff_header (SANE_Frame format, int width, int height, int depth,
case SANE_FRAME_GREEN:
case SANE_FRAME_BLUE:
case SANE_FRAME_RGB:
write_tiff_color_header (stdout, width, height, depth, resolution);
write_tiff_color_header (stdout, width, height, depth, resolution, icc_profile);
break;
default:
if (depth == 1)
write_tiff_bw_header (stdout, width, height, resolution);
else
write_tiff_grey_header (stdout, width, height, depth, resolution);
write_tiff_grey_header (stdout, width, height, depth, resolution, icc_profile);
break;
}
}

Wyświetl plik

@ -17,4 +17,4 @@
void
sanei_write_tiff_header (SANE_Frame format, int width, int height, int depth,
int resolution);
int resolution, const char *icc_profile);