kopia lustrzana https://gitlab.com/sane-project/backends
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 tagDEVEL_2_0_BRANCH-1
rodzic
2b54c3e7c4
commit
d054ded6c1
|
@ -88,13 +88,14 @@ static struct option basic_options[] = {
|
||||||
{"batch-increment", required_argument, NULL, OPTION_BATCH_INCREMENT},
|
{"batch-increment", required_argument, NULL, OPTION_BATCH_INCREMENT},
|
||||||
{"format", required_argument, NULL, OPTION_FORMAT},
|
{"format", required_argument, NULL, OPTION_FORMAT},
|
||||||
{"accept-md5-only", no_argument, NULL, OPTION_MD5},
|
{"accept-md5-only", no_argument, NULL, OPTION_MD5},
|
||||||
|
{"icc-profile", required_argument, NULL, 'i'},
|
||||||
{0, 0, NULL, 0}
|
{0, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OUTPUT_PNM 0
|
#define OUTPUT_PNM 0
|
||||||
#define OUTPUT_TIFF 1
|
#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 */
|
#define STRIP_HEIGHT 256 /* # lines we increment image height */
|
||||||
|
|
||||||
static struct option *all_options;
|
static struct option *all_options;
|
||||||
|
@ -112,6 +113,7 @@ static int resolution_optind = -1, resolution_value = 0;
|
||||||
static SANE_Word window_val[2];
|
static SANE_Word window_val[2];
|
||||||
static int window_val_user[2]; /* is width/height user-specified? */
|
static int window_val_user[2]; /* is width/height user-specified? */
|
||||||
static int accept_only_md5_auth = 0;
|
static int accept_only_md5_auth = 0;
|
||||||
|
static const char *icc_profile = NULL;
|
||||||
|
|
||||||
static void fetch_options (SANE_Device * device);
|
static void fetch_options (SANE_Device * device);
|
||||||
static void scanimage_exit (void);
|
static void scanimage_exit (void);
|
||||||
|
@ -1079,7 +1081,7 @@ scan_it (void)
|
||||||
if (output_format == OUTPUT_TIFF)
|
if (output_format == OUTPUT_TIFF)
|
||||||
sanei_write_tiff_header (parm.format,
|
sanei_write_tiff_header (parm.format,
|
||||||
parm.pixels_per_line, parm.lines,
|
parm.pixels_per_line, parm.lines,
|
||||||
parm.depth, resolution_value);
|
parm.depth, resolution_value, icc_profile);
|
||||||
else
|
else
|
||||||
write_pnm_header (parm.format, parm.pixels_per_line,
|
write_pnm_header (parm.format, parm.pixels_per_line,
|
||||||
parm.lines, parm.depth);
|
parm.lines, parm.depth);
|
||||||
|
@ -1246,7 +1248,7 @@ scan_it (void)
|
||||||
image.height = image.y;
|
image.height = image.y;
|
||||||
if (output_format == OUTPUT_TIFF)
|
if (output_format == OUTPUT_TIFF)
|
||||||
sanei_write_tiff_header (parm.format, parm.pixels_per_line,
|
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
|
else
|
||||||
write_pnm_header (parm.format, image.width, image.height, parm.depth);
|
write_pnm_header (parm.format, image.width, image.height, parm.depth);
|
||||||
if ((output_format == OUTPUT_TIFF) || (image.Bpp == 1)
|
if ((output_format == OUTPUT_TIFF) || (image.Bpp == 1)
|
||||||
|
@ -1495,6 +1497,9 @@ main (int argc, char **argv)
|
||||||
case 'h':
|
case 'h':
|
||||||
help = 1;
|
help = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'i': /* icc profile */
|
||||||
|
icc_profile = optarg;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
++verbose;
|
++verbose;
|
||||||
break;
|
break;
|
||||||
|
@ -1676,7 +1681,8 @@ standard output.\n\
|
||||||
-T, --test test backend thoroughly\n\
|
-T, --test test backend thoroughly\n\
|
||||||
-v, --verbose give even more status messages\n\
|
-v, --verbose give even more status messages\n\
|
||||||
-V, --version print version information\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)
|
if (!devname)
|
||||||
{
|
{
|
||||||
|
|
112
frontend/stiff.c
112
frontend/stiff.c
|
@ -1,5 +1,6 @@
|
||||||
/* Create SANE/tiff headers TIFF interfacing routines for SANE
|
/* Create SANE/tiff headers TIFF interfacing routines for SANE
|
||||||
Copyright (C) 2000 Peter Kirchgessner
|
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
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License as
|
modify it under the terms of the GNU General Public License as
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
/* Changes:
|
/* Changes:
|
||||||
2000-11-19, PK: Color TIFF-header: write 3 values for bits per sample
|
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
|
2001-12-16, PK: Write fill order tag for b/w-images
|
||||||
|
2002-08-27, OR: Added tiff tag for ICC profile
|
||||||
*/
|
*/
|
||||||
#ifdef _AIX
|
#ifdef _AIX
|
||||||
# include "../include/lalloca.h" /* MUST come first for 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
|
static void
|
||||||
write_tiff_grey_header (FILE *fptr, int width, int height, int depth,
|
write_tiff_grey_header (FILE *fptr, int width, int height, int depth,
|
||||||
int resolution)
|
int resolution, const char *icc_profile)
|
||||||
{IFD *ifd;
|
{IFD *ifd;
|
||||||
int header_size = 8, ifd_size;
|
int header_size = 8, ifd_size;
|
||||||
int strip_offset, data_offset, data_size;
|
int strip_offset, data_offset, data_size;
|
||||||
int strip_bytecount;
|
int strip_bytecount;
|
||||||
int ntags;
|
int ntags;
|
||||||
int motorola, bps, maxsamplevalue;
|
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 ();
|
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;
|
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;
|
ifd_size = 2 + ntags*12 + 4;
|
||||||
data_offset = header_size + ifd_size;
|
data_offset = header_size + ifd_size;
|
||||||
strip_offset = data_offset + data_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);
|
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, */
|
/* I prefer motorola format. Its human readable. But for 16 bit, */
|
||||||
/* the image format is defined by SANE to be the native byte order */
|
/* the image format is defined by SANE to be the native byte order */
|
||||||
if (bps == 1)
|
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_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);
|
free_ifd (ifd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_tiff_color_header (FILE *fptr, int width, int height, int depth,
|
write_tiff_color_header (FILE *fptr, int width, int height, int depth,
|
||||||
int resolution)
|
int resolution, const char *icc_profile)
|
||||||
{IFD *ifd;
|
{IFD *ifd;
|
||||||
int header_size = 8, ifd_size;
|
int header_size = 8, ifd_size;
|
||||||
int strip_offset, data_offset, data_size;
|
int strip_offset, data_offset, data_size;
|
||||||
int strip_bytecount;
|
int strip_bytecount;
|
||||||
int ntags;
|
int ntags;
|
||||||
int motorola, bps, maxsamplevalue;
|
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 ();
|
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 */
|
/* the following values must be known in advance */
|
||||||
ntags = 13;
|
ntags = 13;
|
||||||
data_size = 3*2 + 3*2 + 3*2;
|
data_size = 3*2 + 3*2 + 3*2;
|
||||||
|
|
||||||
if (resolution > 0)
|
if (resolution > 0)
|
||||||
{
|
{
|
||||||
ntags += 3;
|
ntags += 3;
|
||||||
data_size += 2*4 + 2*4;
|
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;
|
ifd_size = 2 + ntags*12 + 4;
|
||||||
data_offset = header_size + ifd_size;
|
data_offset = header_size + ifd_size;
|
||||||
strip_offset = data_offset + data_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 */
|
/* max sample value */
|
||||||
add_ifd_entry (ifd, 281, IFDE_TYP_SHORT, 3, data_offset);
|
add_ifd_entry (ifd, 281, IFDE_TYP_SHORT, 3, data_offset);
|
||||||
data_offset += 3*2;
|
data_offset += 3*2;
|
||||||
|
|
||||||
if (resolution > 0)
|
if (resolution > 0)
|
||||||
{
|
{
|
||||||
/* x resolution */
|
/* 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);
|
add_ifd_entry (ifd, 283, IFDE_TYP_RATIONAL, 1, data_offset);
|
||||||
data_offset += 2*4;
|
data_offset += 2*4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolution > 0)
|
if (resolution > 0)
|
||||||
{
|
{
|
||||||
/* resolution unit (dpi) */
|
/* resolution unit (dpi) */
|
||||||
add_ifd_entry (ifd, 296, IFDE_TYP_SHORT, 1, 2);
|
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, */
|
/* I prefer motorola format. Its human readable. But for 16 bit, */
|
||||||
/* the image format is defined by SANE to be the native byte order */
|
/* the image format is defined by SANE to be the native byte order */
|
||||||
if (bps == 1)
|
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_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);
|
free_ifd (ifd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sanei_write_tiff_header (SANE_Frame format, int width, int height, int depth,
|
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. */
|
#ifdef __EMX__ /* OS2 - write in binary mode. */
|
||||||
_fsetmode(stdout, "b");
|
_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_GREEN:
|
||||||
case SANE_FRAME_BLUE:
|
case SANE_FRAME_BLUE:
|
||||||
case SANE_FRAME_RGB:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (depth == 1)
|
if (depth == 1)
|
||||||
write_tiff_bw_header (stdout, width, height, resolution);
|
write_tiff_bw_header (stdout, width, height, resolution);
|
||||||
else
|
else
|
||||||
write_tiff_grey_header (stdout, width, height, depth, resolution);
|
write_tiff_grey_header (stdout, width, height, depth, resolution, icc_profile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
|
|
||||||
void
|
void
|
||||||
sanei_write_tiff_header (SANE_Frame format, int width, int height, int depth,
|
sanei_write_tiff_header (SANE_Frame format, int width, int height, int depth,
|
||||||
int resolution);
|
int resolution, const char *icc_profile);
|
||||||
|
|
Ładowanie…
Reference in New Issue