"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "htmldoc/image.cxx" between
htmldoc-1.9.11-source.tar.gz and htmldoc-1.9.12-source.tar.gz

About: HTMLDOC converts HTML and Markdown source files into indexed HTML, EPUB, PostScript, or PDF files (but doesn’t support CSS).

image.cxx  (htmldoc-1.9.11-source):image.cxx  (htmldoc-1.9.12-source)
/* /*
* Image handling routines for HTMLDOC, a HTML document processing program. * Image handling routines for HTMLDOC, a HTML document processing program.
* *
* Copyright 2011-2017 by Michael R Sweet. * Copyright © 2011-2021 by Michael R Sweet.
* Copyright 1997-2010 by Easy Software Products. All rights reserved. * Copyright © 1997-2010 by Easy Software Products. All rights reserved.
* *
* This program is free software. Distribution and use rights are outlined in * This program is free software. Distribution and use rights are outlined in
* the file "COPYING". * the file "COPYING".
*/ */
/* /*
* Include necessary headers. * Include necessary headers.
*/ */
#include "htmldoc.h" #include "htmldoc.h"
#ifdef HAVE_LIBJPEG
extern "C" { /* Workaround for JPEG header problems... */ extern "C" { /* Workaround for JPEG header problems... */
#include <jpeglib.h> /* JPEG/JFIF image definitions */ # include <jpeglib.h> /* JPEG/JFIF image definitions */
} }
#endif // HAVE_JPEG
#include <png.h> /* Portable Network Graphics (PNG) definitions */ #ifdef HAVE_LIBPNG
# include <png.h> /* Portable Network Graphics (PNG) definitions */
#endif // HAVE_LIBPNG
/* /*
* GIF definitions... * GIF definitions...
*/ */
#define GIF_INTERLACE 0x40 #define GIF_INTERLACE 0x40
#define GIF_COLORMAP 0x80 #define GIF_COLORMAP 0x80
typedef uchar gif_cmap_t[256][3]; typedef uchar gif_cmap_t[256][3];
skipping to change at line 67 skipping to change at line 71
int *gray); int *gray);
static int gif_get_block(FILE *fp, uchar *buffer); static int gif_get_block(FILE *fp, uchar *buffer);
static int gif_get_code (FILE *fp, int code_size, int first_time); static int gif_get_code (FILE *fp, int code_size, int first_time);
static int gif_read_image(FILE *fp, image_t *img, gif_cmap_t cmap, static int gif_read_image(FILE *fp, image_t *img, gif_cmap_t cmap,
int interlace, int transparent); int interlace, int transparent);
static int gif_read_lzw(FILE *fp, int first_time, int input_code_size); static int gif_read_lzw(FILE *fp, int first_time, int input_code_size);
static int image_compare(image_t **img1, image_t **img2); static int image_compare(image_t **img1, image_t **img2);
static int image_load_bmp(image_t *img, FILE *fp, int gray, int load_data); static int image_load_bmp(image_t *img, FILE *fp, int gray, int load_data);
static int image_load_gif(image_t *img, FILE *fp, int gray, int load_data); static int image_load_gif(image_t *img, FILE *fp, int gray, int load_data);
#ifdef HAVE_LIBJPEG
static int image_load_jpeg(image_t *img, FILE *fp, int gray, int load_data); static int image_load_jpeg(image_t *img, FILE *fp, int gray, int load_data);
static void jpeg_error_handler(j_common_ptr);
#endif // HAVE_LIBJPEG
#ifdef HAVE_LIBPNG
static int image_load_png(image_t *img, FILE *fp, int gray, int load_data); static int image_load_png(image_t *img, FILE *fp, int gray, int load_data);
#endif // HAVE_LIBPNG
static void image_need_mask(image_t *img, int scaling = 1); static void image_need_mask(image_t *img, int scaling = 1);
static void image_set_mask(image_t *img, int x, int y, uchar alpha = 0); static void image_set_mask(image_t *img, int x, int y, uchar alpha = 0);
static void jpeg_error_handler(j_common_ptr);
static int read_long(FILE *fp); static int read_long(FILE *fp);
static unsigned short read_word(FILE *fp); static unsigned short read_word(FILE *fp);
static unsigned int read_dword(FILE *fp); static unsigned int read_dword(FILE *fp);
/* /*
* 'gif_read_cmap()' - Read the colormap from a GIF file... * 'gif_read_cmap()' - Read the colormap from a GIF file...
*/ */
static int /* O - 0 on success, -1 on error */ static int /* O - 0 on success, -1 on error */
gif_read_cmap(FILE *fp, /* I - File to read from */ gif_read_cmap(FILE *fp, /* I - File to read from */
skipping to change at line 796 skipping to change at line 807
} }
else else
img = *match; img = *match;
// Load the image as appropriate... // Load the image as appropriate...
if (memcmp(header, "GIF87a", 6) == 0 || if (memcmp(header, "GIF87a", 6) == 0 ||
memcmp(header, "GIF89a", 6) == 0) memcmp(header, "GIF89a", 6) == 0)
status = image_load_gif(img, fp, gray, load_data); status = image_load_gif(img, fp, gray, load_data);
else if (memcmp(header, "BM", 2) == 0) else if (memcmp(header, "BM", 2) == 0)
status = image_load_bmp(img, fp, gray, load_data); status = image_load_bmp(img, fp, gray, load_data);
#ifdef HAVE_LIBPNG
else if (memcmp(header, "\211PNG", 4) == 0) else if (memcmp(header, "\211PNG", 4) == 0)
status = image_load_png(img, fp, gray, load_data); status = image_load_png(img, fp, gray, load_data);
#endif // HAVE_LIBPNG
#ifdef HAVE_LIBJPEG
else if (memcmp(header, "\377\330\377", 3) == 0) else if (memcmp(header, "\377\330\377", 3) == 0)
status = image_load_jpeg(img, fp, gray, load_data); status = image_load_jpeg(img, fp, gray, load_data);
#endif // HAVE_LIBJPEG
else else
{ {
progress_error(HD_ERROR_BAD_FORMAT, "Unknown image file format for \"%s\".", progress_error(HD_ERROR_BAD_FORMAT, "Unknown image file format for \"%s\".",
file_rlookup(filename)); file_rlookup(filename));
fclose(fp); fclose(fp);
free(img); free(img);
return (NULL); return (NULL);
} }
fclose(fp); fclose(fp);
skipping to change at line 1219 skipping to change at line 1234
/* /*
* Read the header; we already know it is a GIF file... * Read the header; we already know it is a GIF file...
*/ */
fread(buf, 13, 1, fp); fread(buf, 13, 1, fp);
img->width = (buf[7] << 8) | buf[6]; img->width = (buf[7] << 8) | buf[6];
img->height = (buf[9] << 8) | buf[8]; img->height = (buf[9] << 8) | buf[8];
ncolors = 2 << (buf[10] & 0x07); ncolors = 2 << (buf[10] & 0x07);
if (img->width <= 0 || img->width > 32767 || img->height <= 0 || img->height >
32767)
return (-1);
// If we are writing an encrypted PDF file, bump the use count so we create // If we are writing an encrypted PDF file, bump the use count so we create
// an image object (Acrobat 6 bug workaround) // an image object (Acrobat 6 bug workaround)
if (Encryption) if (Encryption)
img->use ++; img->use ++;
if (buf[10] & GIF_COLORMAP) if (buf[10] & GIF_COLORMAP)
if (gif_read_cmap(fp, ncolors, cmap, &gray)) if (gif_read_cmap(fp, ncolors, cmap, &gray))
return (-1); return (-1);
transparent = -1; transparent = -1;
skipping to change at line 1305 skipping to change at line 1323
img->pixels = (uchar *)malloc((size_t)(img->width * img->height * img- >depth)); img->pixels = (uchar *)malloc((size_t)(img->width * img->height * img- >depth));
if (img->pixels == NULL) if (img->pixels == NULL)
return (-1); return (-1);
return (gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE, transpare nt)); return (gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE, transpare nt));
} }
} }
} }
#ifdef HAVE_LIBJPEG
typedef struct hd_jpeg_err_s // JPEG error manager extension
{
struct jpeg_error_mgr jerr; // JPEG error manager information
jmp_buf retbuf; // setjmp() return buffer
char message[JMSG_LENGTH_MAX];
// Last error message
} hd_jpeg_err_t;
/* /*
* 'image_load_jpeg()' - Load a JPEG image file. * 'image_load_jpeg()' - Load a JPEG image file.
*/ */
static int /* O - 0 = success, -1 = fail */ static int /* O - 0 = success, -1 = fail */
image_load_jpeg(image_t *img, /* I - Image pointer */ image_load_jpeg(image_t *img, /* I - Image pointer */
FILE *fp, /* I - File to load from */ FILE *fp, /* I - File to load from */
int gray, /* I - 0 = color, 1 = grayscale */ int gray, /* I - 0 = color, 1 = grayscale */
int load_data)/* I - 1 = load image data, 0 = just info */ int load_data)/* I - 1 = load image data, 0 = just info */
{ {
struct jpeg_decompress_struct cinfo; /* Decompressor info */ struct jpeg_decompress_struct cinfo; /* Decompressor info */
struct jpeg_error_mgr jerr; /* Error handler info */ hd_jpeg_err_t jerr; // JPEG error handler
JSAMPROW row; /* Sample row pointer */ JSAMPROW row; /* Sample row pointer */
jpeg_std_error(&jerr); jpeg_std_error(&jerr.jerr);
jerr.error_exit = jpeg_error_handler; jerr.jerr.error_exit = jpeg_error_handler;
cinfo.err = &jerr; if (setjmp(jerr.retbuf))
{
progress_error(HD_ERROR_BAD_FORMAT, "%s (%s)", jerr.message, file_rlookup(i
mg->filename));
jpeg_destroy_decompress(&cinfo);
return (-1);
}
cinfo.err = (struct jpeg_error_mgr *)&jerr;
jpeg_create_decompress(&cinfo); jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, fp); jpeg_stdio_src(&cinfo, fp);
jpeg_read_header(&cinfo, (boolean)1); jpeg_read_header(&cinfo, (boolean)1);
cinfo.quantize_colors = FALSE; cinfo.quantize_colors = FALSE;
if (gray || cinfo.num_components == 1) if (gray || cinfo.num_components == 1)
{ {
cinfo.out_color_space = JCS_GRAYSCALE; cinfo.out_color_space = JCS_GRAYSCALE;
cinfo.out_color_components = 1; cinfo.out_color_components = 1;
skipping to change at line 1384 skipping to change at line 1418
{ {
row = (JSAMPROW)(img->pixels + (size_t)cinfo.output_scanline * (size_t)cinfo .output_width * (size_t)cinfo.output_components); row = (JSAMPROW)(img->pixels + (size_t)cinfo.output_scanline * (size_t)cinfo .output_width * (size_t)cinfo.output_components);
jpeg_read_scanlines(&cinfo, &row, (JDIMENSION)1); jpeg_read_scanlines(&cinfo, &row, (JDIMENSION)1);
} }
jpeg_finish_decompress(&cinfo); jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
return (0); return (0);
} }
#endif // HAVE_LIBJPEG
#ifdef HAVE_LIBPNG
/* /*
* 'image_load_png()' - Load a PNG image file. * 'image_load_png()' - Load a PNG image file.
*/ */
static int /* O - 0 = success, -1 = fail */ static int /* O - 0 = success, -1 = fail */
image_load_png(image_t *img, /* I - Image pointer */ image_load_png(image_t *img, /* I - Image pointer */
FILE *fp, /* I - File to read from */ FILE *fp, /* I - File to read from */
int gray, /* I - 0 = color, 1 = grayscale */ int gray, /* I - 0 = color, 1 = grayscale */
int load_data)/* I - 1 = load image data, 0 = just info */ int load_data)/* I - 1 = load image data, 0 = just info */
{ {
skipping to change at line 1451 skipping to change at line 1487
return (-1); return (-1);
} }
/* /*
* Initialize the PNG read "engine"... * Initialize the PNG read "engine"...
*/ */
png_init_io(pp, fp); png_init_io(pp, fp);
#if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED) # if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED)
// Don't throw errors with "invalid" sRGB profiles produced by Adobe apps. // Don't throw errors with "invalid" sRGB profiles produced by Adobe apps.
png_set_option(pp, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON); png_set_option(pp, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON);
#endif // PNG_SKIP_sRGB_CHECK_PROFILE && PNG_SET_OPTION_SUPPORTED # endif // PNG_SKIP_sRGB_CHECK_PROFILE && PNG_SET_OPTION_SUPPORTED
/* /*
* Get the image dimensions and convert to grayscale or RGB... * Get the image dimensions and convert to grayscale or RGB...
*/ */
png_read_info(pp, info); png_read_info(pp, info);
bit_depth = png_get_bit_depth(pp, info); bit_depth = png_get_bit_depth(pp, info);
color_type = png_get_color_type(pp, info); color_type = png_get_color_type(pp, info);
skipping to change at line 1486 skipping to change at line 1522
// an image object (Acrobat 6 bug workaround) // an image object (Acrobat 6 bug workaround)
if (Encryption) if (Encryption)
img->use ++; img->use ++;
} }
else if (!(color_type & PNG_COLOR_MASK_COLOR) && bit_depth < 8) else if (!(color_type & PNG_COLOR_MASK_COLOR) && bit_depth < 8)
{ {
png_set_expand_gray_1_2_4_to_8(pp); png_set_expand_gray_1_2_4_to_8(pp);
} }
else if (bit_depth == 16) else if (bit_depth == 16)
{ {
#if PNG_LIBPNG_VER >= 10504 # if PNG_LIBPNG_VER >= 10504
png_set_scale_16(pp); png_set_scale_16(pp);
#else # else
png_set_strip_16(pp); png_set_strip_16(pp);
#endif // PNG_LIBPNG_VER >= 10504 # endif // PNG_LIBPNG_VER >= 10504
} }
if (color_type & PNG_COLOR_MASK_COLOR) if (color_type & PNG_COLOR_MASK_COLOR)
{ {
depth = 3; depth = 3;
img->depth = gray ? 1 : 3; img->depth = gray ? 1 : 3;
} }
else else
{ {
depth = 1; depth = 1;
skipping to change at line 1519 skipping to change at line 1555
if ((PSLevel == 0 && PDFVersion >= 14) || PSLevel == 3) if ((PSLevel == 0 && PDFVersion >= 14) || PSLevel == 3)
image_need_mask(img, 8); image_need_mask(img, 8);
else if (PSLevel == 0 && PDFVersion == 13) else if (PSLevel == 0 && PDFVersion == 13)
image_need_mask(img, 2); image_need_mask(img, 2);
else else
image_need_mask(img); image_need_mask(img);
depth ++; depth ++;
} }
#ifdef DEBUG # ifdef DEBUG
printf("bit_depth=%d, color_type=0x%04x, depth=%d, img->width=%d, img->height= %d, img->depth=%d\n", bit_depth, color_type, depth, img->width, img->height, img ->depth); printf("bit_depth=%d, color_type=0x%04x, depth=%d, img->width=%d, img->height= %d, img->depth=%d\n", bit_depth, color_type, depth, img->width, img->height, img ->depth);
if (color_type & PNG_COLOR_MASK_COLOR) if (color_type & PNG_COLOR_MASK_COLOR)
puts(" COLOR"); puts(" COLOR");
else else
puts(" GRAYSCALE"); puts(" GRAYSCALE");
if (color_type & PNG_COLOR_MASK_ALPHA) if (color_type & PNG_COLOR_MASK_ALPHA)
puts(" ALPHA"); puts(" ALPHA");
if (color_type & PNG_COLOR_MASK_PALETTE) if (color_type & PNG_COLOR_MASK_PALETTE)
puts(" PALETTE"); puts(" PALETTE");
#endif // DEBUG # endif // DEBUG
if (!load_data) if (!load_data)
{ {
png_destroy_read_struct(&pp, &info, NULL); png_destroy_read_struct(&pp, &info, NULL);
return (0); return (0);
} }
img->pixels = (uchar *)calloc(1,(size_t)(img->width * img->height * depth)); img->pixels = (uchar *)calloc(1,(size_t)(img->width * img->height * depth));
/* /*
skipping to change at line 1561 skipping to change at line 1597
for (i = png_set_interlace_handling(pp); i > 0; i --) for (i = png_set_interlace_handling(pp); i > 0; i --)
png_read_rows(pp, rows, NULL, (png_uint_32)img->height); png_read_rows(pp, rows, NULL, (png_uint_32)img->height);
/* /*
* Generate the alpha mask as necessary... * Generate the alpha mask as necessary...
*/ */
if (color_type & PNG_COLOR_MASK_ALPHA) if (color_type & PNG_COLOR_MASK_ALPHA)
{ {
#ifdef DEBUG # ifdef DEBUG
for (inptr = img->pixels, i = 0; i < img->height; i ++) for (inptr = img->pixels, i = 0; i < img->height; i ++)
{ {
for (j = 0; j < img->width; j ++, inptr += depth) for (j = 0; j < img->width; j ++, inptr += depth)
switch (depth) switch (depth)
{ {
case 2 : case 2 :
printf(" %02X%02X", inptr[0], inptr[1]); printf(" %02X%02X", inptr[0], inptr[1]);
break; break;
case 4 : case 4 :
printf(" %02X%02X%02X%02X", inptr[0], inptr[1], inptr[2], inptr[3]) ; printf(" %02X%02X%02X%02X", inptr[0], inptr[1], inptr[2], inptr[3]) ;
break; break;
} }
putchar('\n'); putchar('\n');
} }
#endif // DEBUG # endif // DEBUG
for (inptr = img->pixels + depth - 1, i = 0; i < img->height; i ++) for (inptr = img->pixels + depth - 1, i = 0; i < img->height; i ++)
for (j = 0; j < img->width; j ++, inptr += depth) for (j = 0; j < img->width; j ++, inptr += depth)
image_set_mask(img, j, i, *inptr); image_set_mask(img, j, i, *inptr);
} }
/* /*
* Reformat the data as necessary for the reader... * Reformat the data as necessary for the reader...
*/ */
skipping to change at line 1636 skipping to change at line 1672
* Free memory and return... * Free memory and return...
*/ */
free(rows); free(rows);
png_read_end(pp, info); png_read_end(pp, info);
png_destroy_read_struct(&pp, &info, NULL); png_destroy_read_struct(&pp, &info, NULL);
return (0); return (0);
} }
#endif // HAVE_LIBPNG
/* /*
* 'image_need_mask()' - Allocate memory for the image mask... * 'image_need_mask()' - Allocate memory for the image mask...
*/ */
static void static void
image_need_mask(image_t *img, /* I - Image to add mask to */ image_need_mask(image_t *img, /* I - Image to add mask to */
int scaling) /* I - Scaling for mask image */ int scaling) /* I - Scaling for mask image */
{ {
size_t size; /* Byte size of mask image */ size_t size; /* Byte size of mask image */
skipping to change at line 1752 skipping to change at line 1789
else else
img->use --; img->use --;
if (img->use) if (img->use)
return; return;
free(img->pixels); free(img->pixels);
img->pixels = NULL; img->pixels = NULL;
} }
#ifdef HAVE_LIBJPEG
/* /*
* 'jpeg_error_handler()' - Handle JPEG errors by not exiting. * 'jpeg_error_handler()' - Handle JPEG errors by not exiting.
*/ */
static void static void
jpeg_error_handler(j_common_ptr) jpeg_error_handler(j_common_ptr p) // Common JPEG data
{ {
return; hd_jpeg_err_t *jerr = (hd_jpeg_err_t *)p->err;
// JPEG error handler
// Save the error message in the string buffer...
(jerr->jerr.format_message)(p, jerr->message);
// Return to the point we called setjmp()...
longjmp(jerr->retbuf, 1);
} }
#endif // HAVE_LIBJPEG
/* /*
* 'read_word()' - Read a 16-bit unsigned integer. * 'read_word()' - Read a 16-bit unsigned integer.
*/ */
static unsigned short /* O - 16-bit unsigned integer */ static unsigned short /* O - 16-bit unsigned integer */
read_word(FILE *fp) /* I - File to read from */ read_word(FILE *fp) /* I - File to read from */
{ {
unsigned char b0, b1; /* Bytes from file */ unsigned char b0, b1; /* Bytes from file */
 End of changes. 33 change blocks. 
21 lines changed or deleted 69 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)