double int_part;
double frac_row;
double frac_col;
+ double width_scaling;
#endif
uint8_t *row8[2];
uint16_t *row16[2];
input_width = s->input_width - 1;
input_length = s->input_length - 1;
- skip = s->raw_output_row*input_length/output_length;
+ skip = s->raw_output_row*input_length/output_length + 1;
if (skip >= s->raw_input_row)
{
- skip++;
while (skip >= s->raw_input_row)
{
if (s->raw_input_row >= s->input_length)
- {
- s->raw_output_row = -1;
break;
- }
row_len = get_and_scrunch_row(s, s->raw_pixel_row[0]);
if (row_len != s->output_width)
{
frac_row = ((s->raw_output_row*256*input_length)/output_length) & 0xFF;
#else
frac_row = modf((double) s->raw_output_row*input_length/output_length, &int_part);
+ width_scaling = (double) input_width/output_width;
#endif
switch (s->output_format)
buf[3*i + j] = saturateu8(c1 + (((c2 - c1)*frac_row) >> 8));
}
#else
- frac_col = modf((double) i*input_width/output_width, &int_part);
+ frac_col = modf(width_scaling*i, &int_part);
x = 3*int_part;
for (j = 0; j < 3; j++)
{
buf16[3*i + j] = saturateu16(c1 + (((c2 - c1)*frac_row) >> 8));
}
#else
- frac_col = modf((double) i*input_width/output_width, &int_part);
+ frac_col = modf(width_scaling*i, &int_part);
x = 3*int_part;
for (j = 0; j < 3; j++)
{
c2 = row8[1][x] + (((row8[1][x + 1] - row8[1][x])*frac_col) >> 8);
buf[i] = saturateu8(c1 + (((c2 - c1)*frac_row) >> 8));
#else
- frac_col = modf((double) i*input_width/output_width, &int_part);
+ frac_col = modf(width_scaling*i, &int_part);
x = int_part;
c1 = row8[0][x] + (row8[0][x + 1] - row8[0][x])*frac_col;
c2 = row8[1][x] + (row8[1][x + 1] - row8[1][x])*frac_col;
c2 = row16[1][x] + (((row16[1][x + 1] - row16[1][x])*frac_col) >> 8);
buf[i] = saturateu8(c1 + (((c2 - c1)*frac_row) >> 8));
#else
- frac_col = modf((double) i*input_width/output_width, &int_part);
+ frac_col = modf(width_scaling*i, &int_part);
x = int_part;
c1 = row16[0][x] + (row16[0][x + 1] - row16[0][x])*frac_col;
c2 = row16[1][x] + (row16[1][x + 1] - row16[1][x])*frac_col;
float offset_b;
int ab_are_signed;
- /* Illuminant */
+ /* Illuminant, forward and reverse */
float x_n;
float y_n;
float z_n;
+ float x_rn;
+ float y_rn;
+ float z_rn;
};
/* State of a working instance of the T.42 JPEG FAX encoder */
T4_COMPRESSION_SYCC_T81 = 0x200,
/*! T.88 monochrome JBIG2 compression */
T4_COMPRESSION_T88 = 0x400,
+ /*! Uncompressed image. This compression cannot be used for FAXes. It is provided for specifying
+ output formats for received images. */
+ T4_COMPRESSION_UNCOMPRESSED = 0x1000,
+ /*! Conventional JPEG. This compression cannot be used for FAXes. It is provided for specifying
+ output formats for received images. */
+ T4_COMPRESSION_JPEG = 0x2000,
/*! Support solour compression without sub-sampling */
T4_COMPRESSION_NO_SUBSAMPLING = 0x800000,
/*! Gray-scale support by multi-level codecs */
| T4_SUPPORT_LENGTH_A4
| T4_SUPPORT_LENGTH_B4
| T4_SUPPORT_LENGTH_UNLIMITED;
- /* Set the output encoding to something safe. Most things get 1D and 2D
- encoding right. Quite a lot get other things wrong. */
- s->supported_output_compressions = T4_COMPRESSION_T4_2D | T4_COMPRESSION_T42_T81;
+ /* Set the output encoding to something safe. For bi-level images ost things get
+ 1D and 2D encoding right. Quite a lot get other things wrong. */
+ s->supported_output_compressions = T4_COMPRESSION_T4_2D | T4_COMPRESSION_JPEG;
s->local_min_scan_time_code = T30_MIN_SCAN_0MS;
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
span_log_set_protocol(&s->logging, "T.30");
lab->y_n = new_yn;
lab->z_n = new_zn;
}
+ lab->x_rn = 1.0f/lab->x_n;
+ lab->y_rn = 1.0f/lab->y_n;
+ lab->z_rn = 1.0f/lab->z_n;
}
/*- End of function --------------------------------------------------------*/
z = 0.0193f*r + 0.1192f*g + 0.9505f*b;
/* Normalise for the illuminant */
- x /= s->x_n;
- y /= s->y_n;
- z /= s->z_n;
+ x *= s->x_rn;
+ y *= s->y_rn;
+ z *= s->z_rn;
/* XYZ to Lab */
xx = (x <= 0.008856f) ? (7.787f*x + 0.1379f) : cbrtf(x);
{
/* ITU-YCC */
/* Illuminant D65 */
- set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f);
+ //set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f);
+ set_lab_illuminant(&s->lab, 100.0f, 100.0f, 100.0f);
set_lab_gamut(&s->lab, 0, 100, -127, 127, -127, 127, false);
}
else
{
/* ITULAB */
/* Illuminant D50 */
- set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f);
-set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f);
+ //set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f);
+ set_lab_illuminant(&s->lab, 100.0f, 100.0f, 100.0f);
set_lab_gamut(&s->lab, 0, 100, -85, 85, -75, 125, false);
}
s->compressed_image_size = 0;
{
/* ITU-YCC */
/* Illuminant D65 */
- set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f);
+ //set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f);
+ set_lab_illuminant(&s->lab, 100.0f, 100.0f, 100.0f);
set_lab_gamut(&s->lab, 0, 100, -127, 127, -127, 127, false);
}
else
{
/* ITULAB */
/* Illuminant D50 */
- set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f);
-set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f);
+ //set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f);
+ set_lab_illuminant(&s->lab, 100.0f, 100.0f, 100.0f);
set_lab_gamut(&s->lab, 0, 100, -85, 85, -75, 125, false);
}
return "T.43";
case T4_COMPRESSION_T45:
return "T.45";
+ /* Compressions which can only be used in TIFF files */
+ case T4_COMPRESSION_UNCOMPRESSED:
+ return "Uncompressed";
+ case T4_COMPRESSION_JPEG:
+ return "JPEG";
}
return "???";
}
break;
#endif
#if defined(SPANDSP_SUPPORT_T42)
+ case T4_COMPRESSION_JPEG:
+ output_compression = COMPRESSION_JPEG;
+ bits_per_sample = 8;
+ if (t->image_type == T4_IMAGE_TYPE_COLOUR_8BIT)
+ {
+ samples_per_pixel = 3;
+ photometric = PHOTOMETRIC_YCBCR;
+ }
+ else
+ {
+ samples_per_pixel = 1;
+ photometric = PHOTOMETRIC_MINISBLACK;
+ }
+ break;
case T4_COMPRESSION_T42_T81:
output_compression = COMPRESSION_JPEG;
bits_per_sample = 8;
if (t->image_type == T4_IMAGE_TYPE_COLOUR_8BIT)
{
samples_per_pixel = 3;
- photometric = PHOTOMETRIC_YCBCR; //PHOTOMETRIC_ITULAB;
+ photometric = PHOTOMETRIC_ITULAB;
}
else
{
TIFFSetField(t->tiff_file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(t->tiff_file, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(t->tiff_file, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB);
- if (t->compression == T4_COMPRESSION_T42_T81)
+ switch (t->compression)
{
+ case T4_COMPRESSION_JPEG:
+ TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 2, 2);
+ //TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 1, 1);
+ TIFFSetField(t->tiff_file, TIFFTAG_JPEGQUALITY, 75);
+ TIFFSetField(t->tiff_file, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
+ break;
+ case T4_COMPRESSION_T42_T81:
TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 2, 2);
//TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 1, 1);
TIFFSetField(t->tiff_file, TIFFTAG_JPEGQUALITY, 75);
TIFFSetField(t->tiff_file, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
+ break;
}
/* TIFFTAG_STRIPBYTECOUNTS and TIFFTAG_STRIPOFFSETS are added automatically */
}
else
{
- if ((s->supported_tiff_compressions & T4_COMPRESSION_T42_T81))
+ if ((s->supported_tiff_compressions & T4_COMPRESSION_JPEG))
+ s->tiff.compression = T4_COMPRESSION_JPEG;
+ else if ((s->supported_tiff_compressions & T4_COMPRESSION_T42_T81))
s->tiff.compression = T4_COMPRESSION_T42_T81;
else if ((s->supported_tiff_compressions & T4_COMPRESSION_T43))
s->tiff.compression = T4_COMPRESSION_T43;
+ else if ((s->supported_tiff_compressions & T4_COMPRESSION_UNCOMPRESSED))
+ s->tiff.compression = T4_COMPRESSION_UNCOMPRESSED;
}
s->tiff.image_type = output_image_type;
}
/* We can't rework a bilevel image that fits none of the patterns */
if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL)
return T4_IMAGE_FORMAT_NORESSUPPORT;
+ if (!(supported_compressions & T4_COMPRESSION_RESCALING))
+ return T4_IMAGE_FORMAT_NORESSUPPORT;
res = T4_IMAGE_FORMAT_OK;
/* Any other kind of image might be resizable */
s->metadata.image_width = T4_WIDTH_200_A4;
{
t30_set_supported_colour_resolutions(t30_state[i], 0);
}
- //t30_set_supported_output_compressions(t30_state[i], T4_COMPRESSION_T85);
+ t30_set_supported_output_compressions(t30_state[i], T4_COMPRESSION_T6 | T4_COMPRESSION_JPEG);
t30_set_ecm_capability(t30_state[i], use_ecm);
t30_set_supported_compressions(t30_state[i],
T4_COMPRESSION_T4_1D