Compare commits

..

14 Commits

Author SHA1 Message Date
Thierry LARONDE
7a54ed8e16
Merge d032483ed471b76ec56d89e5a7e5951917fe5562 into b2fc82f3a8248e54707e1f21e29fa9b2a7831d73 2025-02-12 14:54:51 +00:00
Thierry LARONDE
d032483ed4
Merge branch 'michaelrsweet:master' into info 2025-02-12 15:54:47 +01:00
Michael R Sweet
b2fc82f3a8
Update CI dependencies.
Add libpng_native to VC++ projects.
2025-02-12 09:25:57 -05:00
Michael R Sweet
b81d01f319
Fix builds without libpng. 2025-02-11 22:59:23 -05:00
Michael R Sweet
1b35321615
Add PngSuite to testpdfio (Issue #90) 2025-02-11 22:54:59 -05:00
Michael R Sweet
990342f2a5
Add masking, color space, and variable bit depth support (Issue #90) 2025-02-11 22:07:02 -05:00
Michael R Sweet
7f5fc456bc
Fix image dictionary for new libpng-based PNG image support (Issue #90) 2025-02-11 20:23:59 -05:00
Michael R Sweet
7c527cc908
Fix pdfio-512.png file. 2025-02-11 20:23:28 -05:00
Michael R Sweet
41d17fc4e3
Update version number in NuGet files. 2025-02-11 20:23:17 -05:00
Michael R Sweet
4e89137689
Use pkg-config for compiler options.
Fix some issues with the image2pdf example code.
2025-02-11 20:22:36 -05:00
Michael R Sweet
e686669b9d
Save work on libpng PNG loader (Issue #90) 2025-02-10 21:25:59 -05:00
Michael R Sweet
1e5cc6ffd5
Do cleanup of PNG loading code, in preparation of adding full support (Issue #90) 2025-02-10 15:54:29 -05:00
Michael R Sweet
4f1b373232
Add PngSuite from http://www.schaik.com/pngsuite/ for testing PNG image
support (Issue #90)
2025-02-10 11:04:39 -05:00
Michael R Sweet
6f4bfe107f
Refactor pdfioFileCreateImageObjFromData to do the image writing in a separate
function (Issue #90)
2025-02-10 10:28:28 -05:00
97 changed files with 838 additions and 230 deletions

View File

@ -17,7 +17,7 @@ jobs:
- name: Update Build Environment
run: sudo apt-get update --fix-missing -y
- name: Install Prerequisites
run: sudo apt-get install -y cppcheck zlib1g-dev
run: sudo apt-get install -y cppcheck zlib1g-dev libpng-dev
- name: Configure PDFio
run: ./configure --enable-debug --enable-sanitizer --enable-maintainer
- name: Build PDFio

View File

@ -32,7 +32,7 @@ jobs:
run: sudo apt-get update --fix-missing -y
- name: Install Prerequisites
run: sudo apt-get install -y zlib1g-dev
run: sudo apt-get install -y zlib1g-dev libpng-dev
- name: Initialize CodeQL
uses: github/codeql-action/init@v2

View File

@ -12,7 +12,7 @@ jobs:
- name: Update Build Environment
run: sudo apt-get update --fix-missing -y
- name: Install Prerequisites
run: sudo apt-get install -y zlib1g-dev
run: sudo apt-get install -y zlib1g-dev libpng-dev
- name: Download Coverity Build Tool
run: |
wget -q https://scan.coverity.com/download/linux64 --post-data token="$TOKEN&project=$GITHUB_REPOSITORY" -O cov-analysis-linux64.tar.gz

View File

@ -1,9 +1,10 @@
Changes in PDFio
================
v1.?.? - YYYY-MM-DD
v1.5.0 - YYYY-MM-DD
-------------------
- Added support for using libpng to embed PNG images in PDF output (Issue #90)
- Updated the pdf2txt example to support font encodings.

77
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for pdfio 1.4.1.
# Generated by GNU Autoconf 2.71 for pdfio 1.5.0.
#
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
#
@ -610,8 +610,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='pdfio'
PACKAGE_TARNAME='pdfio'
PACKAGE_VERSION='1.4.1'
PACKAGE_STRING='pdfio 1.4.1'
PACKAGE_VERSION='1.5.0'
PACKAGE_STRING='pdfio 1.5.0'
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
PACKAGE_URL='https://www.msweet.org/pdfio'
@ -653,6 +653,7 @@ WARNINGS
CSFLAGS
LIBPDFIO_STATIC
LIBPDFIO
PKGCONFIG_LIBPNG
PKGCONFIG_REQUIRES
PKGCONFIG_LIBS_PRIVATE
PKGCONFIG_LIBS
@ -729,6 +730,7 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_libpng
enable_static
enable_shared
enable_debug
@ -1293,7 +1295,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures pdfio 1.4.1 to adapt to many kinds of systems.
\`configure' configures pdfio 1.5.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1359,7 +1361,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of pdfio 1.4.1:";;
short | recursive ) echo "Configuration of pdfio 1.5.0:";;
esac
cat <<\_ACEOF
@ -1367,6 +1369,8 @@ Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-libpng use libpng for pdfioFileCreateImageObjFromFile,
default=auto
--disable-static do not install static library
--enable-shared install shared library
--enable-debug turn on debugging, default=no
@ -1456,7 +1460,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
pdfio configure 1.4.1
pdfio configure 1.5.0
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@ -1612,7 +1616,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by pdfio $as_me 1.4.1, which was
It was created by pdfio $as_me 1.5.0, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@ -2368,9 +2372,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
PDFIO_VERSION="1.4.1"
PDFIO_VERSION_MAJOR="`echo 1.4.1 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.4.1 | awk -F. '{printf("%d\n",$2);}'`"
PDFIO_VERSION="1.5.0"
PDFIO_VERSION_MAJOR="`echo 1.5.0 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.5.0 | awk -F. '{printf("%d\n",$2);}'`"
@ -4099,6 +4103,55 @@ fi
fi
# Check whether --enable-libpng was given.
if test ${enable_libpng+y}
then :
enableval=$enable_libpng;
fi
PKGCONFIG_LIBPNG=""
if test "x$PKGCONFIG" != x -a x$enable_libpng != xno
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libpng-1.6.x" >&5
printf %s "checking for libpng-1.6.x... " >&6; }
if $PKGCONFIG --exists libpng16
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; };
printf "%s\n" "#define HAVE_LIBPNG 1" >>confdefs.h
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
PKGCONFIG_LIBPNG="libpng >= 1.6,"
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE"
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; };
if test x$enable_libpng = xyes
then :
as_fn_error $? "libpng-dev 1.6 or later required for --enable-libpng." "$LINENO" 5
fi
fi
elif test x$enable_libpng = xyes
then :
as_fn_error $? "libpng-dev 1.6 or later required for --enable-libpng." "$LINENO" 5
fi
# Check whether --enable-static was given.
if test ${enable_static+y}
then :
@ -4935,7 +4988,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by pdfio $as_me 1.4.1, which was
This file was extended by pdfio $as_me 1.5.0, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -4991,7 +5044,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
pdfio config.status 1.4.1
pdfio config.status 1.5.0
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"

View File

@ -1,7 +1,7 @@
dnl
dnl Configuration script for PDFio
dnl
dnl Copyright © 2023-2024 by Michael R Sweet
dnl Copyright © 2023-2025 by Michael R Sweet
dnl
dnl Licensed under Apache License v2.0. See the file "LICENSE" for more
dnl information.
@ -21,7 +21,7 @@ AC_PREREQ([2.70])
dnl Package name and version...
AC_INIT([pdfio], [1.4.1], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
AC_INIT([pdfio], [1.5.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
PDFIO_VERSION="AC_PACKAGE_VERSION"
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
@ -121,6 +121,32 @@ AS_IF([$PKGCONFIG --exists zlib], [
])
dnl libpng...
AC_ARG_ENABLE([libpng], AS_HELP_STRING([--enable-libpng], [use libpng for pdfioFileCreateImageObjFromFile, default=auto]))
PKGCONFIG_LIBPNG=""
AC_SUBST([PKGCONFIG_LIBPNG])
AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
AC_MSG_CHECKING([for libpng-1.6.x])
AS_IF([$PKGCONFIG --exists libpng16], [
AC_MSG_RESULT([yes]);
AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?])
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
PKGCONFIG_LIBPNG="libpng >= 1.6,"
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE"
], [
AC_MSG_RESULT([no]);
AS_IF([test x$enable_libpng = xyes], [
AC_MSG_ERROR([libpng-dev 1.6 or later required for --enable-libpng.])
])
])
], [test x$enable_libpng = xyes], [
AC_MSG_ERROR([libpng-dev 1.6 or later required for --enable-libpng.])
])
dnl Library target...
AC_ARG_ENABLE([static], AS_HELP_STRING([--disable-static], [do not install static library]))
AC_ARG_ENABLE([shared], AS_HELP_STRING([--enable-shared], [install shared library]))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -14,8 +14,8 @@
# Common options
CFLAGS = -g $(CPPFLAGS)
#CFLAGS = -g -fsanitize=address $(CPPFLAGS)
CPPFLAGS = -I.. -I/usr/local/include
LIBS = -L.. -L/usr/local/lib -lpdfio -lz -lm
CPPFLAGS = -I.. $(shell PKG_CONFIG_PATH="..:$(PKG_CONFIG_PATH)" pkg-config pdfio --cflags)
LIBS = -L.. $(shell PKG_CONFIG_PATH="..:$(PKG_CONFIG_PATH)" pkg-config pdfio --libs)
# Targets

View File

@ -1,7 +1,7 @@
//
// Image example for PDFio.
//
// Copyright © 2023-2024 by Michael R Sweet.
// Copyright © 2023-2025 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@ -22,8 +22,8 @@
bool // O - True on success, false on failure
create_pdf_image_file(
const char *pdfname, // I - PDF filename
const char *imagename, // I - Image filename
const char *pdfname, // I - PDF filename
const char *caption) // I - Caption filename
{
pdfio_file_t *pdf; // PDF file
@ -36,6 +36,15 @@ create_pdf_image_file(
double tx, ty; // Position on page
// Default the caption...
if (!caption)
{
if ((caption = strrchr(imagename, '/')) != NULL)
caption ++;
else
caption = imagename;
}
// Create the PDF file...
pdf = pdfioFileCreate(pdfname, /*version*/NULL, /*media_box*/NULL,
/*crop_box*/NULL, /*error_cb*/NULL,

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="libpng_native" version="1.6.30" targetFramework="native" />
<package id="libpng_native.redist" version="1.6.30" targetFramework="native" />
<package id="zlib_native" version="1.2.11" targetFramework="native" />
<package id="zlib_native.redist" version="1.2.11" targetFramework="native" />
</packages>

View File

@ -1,7 +1,7 @@
//
// Content helper functions for PDFio.
//
// Copyright © 2021-2024 by Michael R Sweet.
// Copyright © 2021-2025 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@ -11,6 +11,9 @@
#include "pdfio-content.h"
#include "pdfio-base-font-widths.h"
#include "ttf.h"
#ifdef HAVE_LIBPNG
# include <png.h>
#endif // HAVE_LIBPNG
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846264338327950288
@ -29,12 +32,50 @@
#define _PDFIO_PNG_CHUNK_gAMA 0x67414d41 // Gamma correction
#define _PDFIO_PNG_CHUNK_tRNS 0x74524e53 // Transparency information
#define _PDFIO_PNG_COMPRESSION_FLATE 0 // Flate compression
#define _PDFIO_PNG_FILTER_ADAPTIVE 0 // Adaptive filtering
#define _PDFIO_PNG_INTERLACE_NONE 0 // No interlacing
#define _PDFIO_PNG_INTERLACE_ADAM 1 // "Adam7" interlacing
#define _PDFIO_PNG_TYPE_GRAY 0 // Grayscale
#define _PDFIO_PNG_TYPE_RGB 2 // RGB
#define _PDFIO_PNG_TYPE_INDEXED 3 // Indexed
#define _PDFIO_PNG_TYPE_GRAYA 4 // Grayscale + alpha
#define _PDFIO_PNG_TYPE_RGBA 6 // RGB + alpha
//
// Local types...
//
typedef pdfio_obj_t *(*_pdfio_image_func_t)(pdfio_dict_t *dict, int fd);
//
// Local functions...
//
static pdfio_obj_t *copy_jpeg(pdfio_dict_t *dict, int fd);
static pdfio_obj_t *copy_png(pdfio_dict_t *dict, int fd);
static bool create_cp1252(pdfio_file_t *pdf);
static pdfio_obj_t *create_image(pdfio_dict_t *dict, const unsigned char *data, size_t width, size_t height, size_t depth, size_t num_colors, bool alpha);
#ifdef HAVE_LIBPNG
static void png_error_func(png_structp pp, png_const_charp message);
static void png_read_func(png_structp png_ptr, png_bytep data, size_t length);
#endif // HAVE_LIBPNG
static void ttf_error_cb(pdfio_file_t *pdf, const char *message);
#ifndef HAVE_LIBPNG
static unsigned update_png_crc(unsigned crc, const unsigned char *buffer, size_t length);
#endif // !HAVE_LIBPNG
static bool write_string(pdfio_stream_t *st, bool unicode, const char *s, bool *newline);
//
// Local globals...
//
static int _pdfio_cp1252[] = // CP1252-specific character mapping
{
0x20AC,
@ -71,30 +112,7 @@ static int _pdfio_cp1252[] = // CP1252-specific character mapping
0x0178
};
//
// Local types...
//
typedef pdfio_obj_t *(*_pdfio_image_func_t)(pdfio_dict_t *dict, int fd);
//
// Local functions...
//
static pdfio_obj_t *copy_jpeg(pdfio_dict_t *dict, int fd);
static pdfio_obj_t *copy_png(pdfio_dict_t *dict, int fd);
static bool create_cp1252(pdfio_file_t *pdf);
static void ttf_error_cb(pdfio_file_t *pdf, const char *message);
static unsigned update_png_crc(unsigned crc, const unsigned char *buffer, size_t length);
static bool write_string(pdfio_stream_t *st, bool unicode, const char *s, bool *newline);
//
// Local globals...
//
#ifndef HAVE_LIBPNG
static unsigned png_crc_table[256] = // CRC-32 table for PNG files
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
@ -141,6 +159,7 @@ static unsigned png_crc_table[256] = // CRC-32 table for PNG files
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#endif // !HAVE_LIBPNG
//
@ -1976,18 +1995,7 @@ pdfioFileCreateImageObjFromData(
bool alpha, // I - `true` if data contains an alpha channel
bool interpolate) // I - Interpolate image data?
{
pdfio_dict_t *dict, // Image dictionary
*decode; // DecodeParms dictionary
pdfio_obj_t *obj, // Image object
*mask_obj = NULL;
// Mask image object, if any
pdfio_stream_t *st; // Image stream
size_t x, y, // X and Y position in image
bpp, // Bytes per pixel
linelen; // Line length
const unsigned char *dataptr; // Pointer into image data
unsigned char *line = NULL, // Current line
*lineptr; // Pointer into line
pdfio_dict_t *dict; // Image dictionary
static const char *defcolors[] = // Default ColorSpace values
{
NULL,
@ -2002,74 +2010,9 @@ pdfioFileCreateImageObjFromData(
if (!pdf || !data || !width || !height || num_colors < 1 || num_colors == 2 || num_colors > 4)
return (NULL);
// Allocate memory for one line of data...
bpp = alpha ? num_colors + 1 : num_colors;
linelen = num_colors * width;
if ((line = malloc(linelen)) == NULL)
return (NULL);
// Generate a mask image, as needed...
if (alpha)
{
// Create the image mask dictionary...
if ((dict = pdfioDictCreate(pdf)) == NULL)
{
free(line);
return (NULL);
}
pdfioDictSetName(dict, "Type", "XObject");
pdfioDictSetName(dict, "Subtype", "Image");
pdfioDictSetNumber(dict, "Width", width);
pdfioDictSetNumber(dict, "Height", height);
pdfioDictSetNumber(dict, "BitsPerComponent", 8);
pdfioDictSetName(dict, "ColorSpace", "DeviceGray");
pdfioDictSetName(dict, "Filter", "FlateDecode");
if ((decode = pdfioDictCreate(pdf)) == NULL)
{
free(line);
return (NULL);
}
pdfioDictSetNumber(decode, "BitsPerComponent", 8);
pdfioDictSetNumber(decode, "Colors", 1);
pdfioDictSetNumber(decode, "Columns", width);
pdfioDictSetNumber(decode, "Predictor", _PDFIO_PREDICTOR_PNG_AUTO);
pdfioDictSetDict(dict, "DecodeParms", decode);
// Create the mask object and write the mask image...
if ((mask_obj = pdfioFileCreateObj(pdf, dict)) == NULL)
{
free(line);
return (NULL);
}
if ((st = pdfioObjCreateStream(mask_obj, PDFIO_FILTER_FLATE)) == NULL)
{
free(line);
pdfioObjClose(mask_obj);
return (NULL);
}
for (y = height, dataptr = data + num_colors; y > 0; y --)
{
for (x = width, lineptr = line; x > 0; x --, dataptr += bpp)
*lineptr++ = *dataptr;
pdfioStreamWrite(st, line, width);
}
pdfioStreamClose(st);
}
// Now create the image...
// Create the image dictionary...
if ((dict = pdfioDictCreate(pdf)) == NULL)
{
free(line);
return (NULL);
}
pdfioDictSetName(dict, "Type", "XObject");
pdfioDictSetName(dict, "Subtype", "Image");
@ -2077,83 +2020,14 @@ pdfioFileCreateImageObjFromData(
pdfioDictSetNumber(dict, "Width", width);
pdfioDictSetNumber(dict, "Height", height);
pdfioDictSetNumber(dict, "BitsPerComponent", 8);
pdfioDictSetName(dict, "Filter", "FlateDecode");
if (color_data)
pdfioDictSetArray(dict, "ColorSpace", color_data);
else
pdfioDictSetName(dict, "ColorSpace", defcolors[num_colors]);
if (mask_obj)
pdfioDictSetObj(dict, "SMask", mask_obj);
if ((decode = pdfioDictCreate(pdf)) == NULL)
{
free(line);
return (NULL);
}
pdfioDictSetNumber(decode, "BitsPerComponent", 8);
pdfioDictSetNumber(decode, "Colors", num_colors);
pdfioDictSetNumber(decode, "Columns", width);
pdfioDictSetNumber(decode, "Predictor", _PDFIO_PREDICTOR_PNG_AUTO);
pdfioDictSetDict(dict, "DecodeParms", decode);
if ((obj = pdfioFileCreateObj(pdf, dict)) == NULL)
{
free(line);
return (NULL);
}
if ((st = pdfioObjCreateStream(obj, PDFIO_FILTER_FLATE)) == NULL)
{
free(line);
pdfioObjClose(obj);
return (NULL);
}
for (y = height, dataptr = data; y > 0; y --)
{
if (alpha)
{
switch (num_colors)
{
case 1 :
for (x = width, lineptr = line; x > 0; x --, dataptr += bpp)
*lineptr++ = *dataptr;
break;
case 3 :
for (x = width, lineptr = line; x > 0; x --, dataptr += bpp)
{
*lineptr++ = dataptr[0];
*lineptr++ = dataptr[1];
*lineptr++ = dataptr[2];
}
break;
case 4 :
for (x = width, lineptr = line; x > 0; x --, dataptr += bpp)
{
*lineptr++ = dataptr[0];
*lineptr++ = dataptr[1];
*lineptr++ = dataptr[2];
*lineptr++ = dataptr[3];
}
break;
}
pdfioStreamWrite(st, line, linelen);
}
else
{
pdfioStreamWrite(st, dataptr, linelen);
dataptr += linelen;
}
}
free(line);
pdfioStreamClose(st);
return (obj);
// Create the image object(s)...
return (create_image(dict, data, width, height, 8, num_colors, alpha));
}
@ -2183,6 +2057,8 @@ pdfioFileCreateImageObjFromFile(
_pdfio_image_func_t copy_func = NULL; // Image copy function
PDFIO_DEBUG("pdfioFileCreateImageObjFromFile(pdf=%p, filename=\"%s\", interpolate=%s)\n", (void *)pdf, filename, interpolate ? "true" : "false");
// Range check input...
if (!pdf || !filename)
return (NULL);
@ -2204,6 +2080,8 @@ pdfioFileCreateImageObjFromFile(
lseek(fd, 0, SEEK_SET);
PDFIO_DEBUG("pdfioFileCreateImageObjFromFile: buffer=<%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X>\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15], buffer[16], buffer[17], buffer[18], buffer[19], buffer[20], buffer[21], buffer[22], buffer[23], buffer[24], buffer[25], buffer[26], buffer[27], buffer[28], buffer[29], buffer[30], buffer[31]);
if (!memcmp(buffer, "\211PNG\015\012\032\012\000\000\000\015IHDR", 16))
{
// PNG image...
@ -2606,8 +2484,198 @@ copy_png(pdfio_dict_t *dict, // I - Dictionary
int fd) // I - File descriptor
{
pdfio_obj_t *obj = NULL; // Object
pdfio_stream_t *st = NULL; // Stream for PNG data
double gamma = 2.2, // Gamma value
wx = 0.0, wy = 0.0, // White point chromacity
rx = 0.0, ry = 0.0, // Red chromacity
gx = 0.0, gy = 0.0, // Green chromacity
bx = 0.0, by = 0.0; // Blue chromacity
#ifdef HAVE_LIBPNG
png_structp pp = NULL; // PNG read pointer
png_infop info = NULL; // PNG info pointers
png_bytep *rows = NULL; // PNG row pointers
unsigned char *pixels = NULL; // PNG image data
unsigned i, // Looping var
color_type, // PNG color mode
width, // Width in columns
height, // Height in lines
depth, // Bit depth
num_colors = 0, // Number of colors
linesize; // Bytes per line
bool alpha; // Alpha transparency?
png_color *palette; // Color palette information
int num_palette; // Number of colors
int num_trans; // Number of transparent colors
png_color_16 *trans; // Transparent colors
PDFIO_DEBUG("copy_png(dict=%p, fd=%d)\n", (void *)dict, fd);
// Allocate memory for PNG reader structures...
if ((pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)dict->pdf, png_error_func, png_error_func)) == NULL)
{
_pdfioFileError(dict->pdf, "Unable to allocate memory for PNG file: %s", strerror(errno));
goto finish_png;
}
if ((info = png_create_info_struct(pp)) == NULL)
{
_pdfioFileError(dict->pdf, "Unable to allocate memory for PNG file: %s", strerror(errno));
goto finish_png;
}
PDFIO_DEBUG("copy_png: pp=%p, info=%p\n", (void *)pp, (void *)info);
if (setjmp(png_jmpbuf(pp)))
{
// If we get here, PNG loading failed and any errors/warnings were logged
// via the corresponding callback functions...
fputs("copy_png: setjmp error handler called.\n", stderr);
goto finish_png;
}
// Set max image size to 16384x16384...
png_set_user_limits(pp, 16384, 16384);
// Read from the file descriptor...
png_set_read_fn(pp, &fd, png_read_func);
// Don't throw errors with "invalid" sRGB profiles produced by Adobe apps.
# if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED)
png_set_option(pp, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON);
# endif // PNG_SKIP_sRGB_CHECK_PROFILE && PNG_SET_OPTION_SUPPORTED
// Get the image dimensions and depth...
png_read_info(pp, info);
width = png_get_image_width(pp, info);
height = png_get_image_height(pp, info);
depth = png_get_bit_depth(pp, info);
color_type = png_get_color_type(pp, info);
if (color_type & PNG_COLOR_MASK_PALETTE)
num_colors = 1;
else if (color_type & PNG_COLOR_MASK_COLOR)
num_colors = 3;
else
num_colors = 1;
PDFIO_DEBUG("copy_png: width=%u, height=%u, depth=%u, color_type=%u, num_colors=%d\n", width, height, depth, color_type, num_colors);
// Set decoding options...
alpha = (color_type & PNG_COLOR_MASK_ALPHA) != 0;
linesize = (width * num_colors * depth + 7) / 8;
if (alpha)
linesize += width;
PDFIO_DEBUG("copy_png: alpha=%s, linesize=%u\n", alpha ? "true" : "false", (unsigned)linesize);
// Allocate memory for the image...
if ((pixels = (unsigned char *)calloc(height, linesize)) == NULL)
{
_pdfioFileError(dict->pdf, "Unable to allocate memory for PNG image: %s", strerror(errno));
goto finish_png;
}
if ((rows = (png_bytep *)calloc((size_t)height, sizeof(png_bytep))) == NULL)
{
_pdfioFileError(dict->pdf, "Unable to allocate memory for PNG image: %s", strerror(errno));
goto finish_png;
}
for (i = 0; i < height; i ++)
rows[i] = pixels + i * linesize;
// Read the image...
for (i = png_set_interlace_handling(pp); i > 0; i --)
png_read_rows(pp, rows, NULL, (png_uint_32)height);
// Add image dictionary information...
pdfioDictSetNumber(dict, "Width", width);
pdfioDictSetNumber(dict, "Height", height);
pdfioDictSetNumber(dict, "BitsPerComponent", depth);
// Grab any color space/palette information...
if (png_get_PLTE(pp, info, &palette, &num_palette))
{
pdfioDictSetArray(dict, "ColorSpace", pdfioArrayCreateColorFromPalette(dict->pdf, num_palette, (unsigned char *)palette));
}
else if (png_get_cHRM(pp, info, &wx, &wy, &rx, &ry, &gx, &gy, &bx, &by) && png_get_gAMA(pp, info, &gamma))
{
pdfioDictSetArray(dict, "ColorSpace", pdfioArrayCreateColorFromPrimaries(dict->pdf, num_colors, gamma, wx, wy, rx, ry, gx, gy, bx, by));
}
else
{
// Default to sRGB...
pdfioDictSetArray(dict, "ColorSpace", pdfioArrayCreateColorFromStandard(dict->pdf, num_colors, PDFIO_CS_SRGB));
}
if (png_get_tRNS(pp, info, /*trans_alpha*/NULL, &num_trans, &trans))
{
int m; // Looping var
pdfio_array_t *mask; // Mask array
mask = pdfioArrayCreate(dict->pdf);
if (color_type & PNG_COLOR_MASK_PALETTE)
{
// List color indices that are transparent...
for (m = 0; m < num_trans; m ++)
{
pdfioArrayAppendNumber(mask, trans[m].index);
pdfioArrayAppendNumber(mask, trans[m].index);
}
}
else if (num_colors == 1)
{
// List grayscale values that are transparent...
for (m = 0; m < num_trans; m ++)
{
pdfioArrayAppendNumber(mask, trans[m].gray >> (16 - depth));
pdfioArrayAppendNumber(mask, trans[m].gray >> (16 - depth));
}
}
else
{
// List RGB color values that are transparent...
for (m = 0; m < num_trans; m ++)
{
pdfioArrayAppendNumber(mask, trans[m].red >> (16 - depth));
pdfioArrayAppendNumber(mask, trans[m].green >> (16 - depth));
pdfioArrayAppendNumber(mask, trans[m].blue >> (16 - depth));
pdfioArrayAppendNumber(mask, trans[m].red >> (16 - depth));
pdfioArrayAppendNumber(mask, trans[m].green >> (16 - depth));
pdfioArrayAppendNumber(mask, trans[m].blue >> (16 - depth));
}
}
pdfioDictSetArray(dict, "Mask", mask);
}
// Create the image object...
obj = create_image(dict, pixels, width, height, depth, num_colors, alpha);
finish_png:
if (pp && info)
{
png_read_end(pp, info);
png_destroy_read_struct(&pp, &info, NULL);
pp = NULL;
info = NULL;
}
free(pixels);
pixels = NULL;
free(rows);
rows = NULL;
return (obj);
#else
pdfio_dict_t *decode = NULL; // Parameters for PNG decode
pdfio_stream_t *st = NULL; // Stream for PNG data
ssize_t bytes; // Bytes read
unsigned char buffer[16384]; // Read buffer
unsigned i, // Looping var
@ -2616,14 +2684,11 @@ copy_png(pdfio_dict_t *dict, // I - Dictionary
crc, // CRC-32
temp, // Temporary value
width = 0, // Width
height = 0; // Height
height = 0, // Height
num_colors = 0; // Number of colors
unsigned char bit_depth = 0, // Bit depth
color_type = 0; // Color type
double gamma = 2.2, // Gamma value
wx = 0.0, wy = 0.0, // White point chromacity
rx = 0.0, ry = 0.0, // Red chromacity
gx = 0.0, gy = 0.0, // Green chromacity
bx = 0.0, by = 0.0; // Blue chromacity
color_type = 0, // Color type
interlace = 0; // Interlace type
pdfio_array_t *mask = NULL; // Color masking array
@ -2727,18 +2792,55 @@ copy_png(pdfio_dict_t *dict, // I - Dictionary
return (NULL);
}
crc = update_png_crc(crc, buffer, length);
width = (unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]);
height = (unsigned)((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]);
bit_depth = buffer[8];
color_type = buffer[9];
crc = update_png_crc(crc, buffer, length);
width = (unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]);
height = (unsigned)((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]);
if (width == 0 || height == 0 || (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8 && bit_depth != 16) || (color_type != _PDFIO_PNG_TYPE_GRAY && color_type != _PDFIO_PNG_TYPE_RGB && color_type != _PDFIO_PNG_TYPE_INDEXED) || buffer[10] || buffer[11] || buffer[12])
if (width == 0 || height == 0)
{
_pdfioFileError(dict->pdf, "Unsupported PNG image.");
_pdfioFileError(dict->pdf, "Unsupported PNG dimensions %ux%u.", (unsigned)width, (unsigned)height);
return (NULL);
}
bit_depth = buffer[8];
color_type = buffer[9];
if (color_type != _PDFIO_PNG_TYPE_GRAY && color_type != _PDFIO_PNG_TYPE_RGB && color_type != _PDFIO_PNG_TYPE_INDEXED)
{
_pdfioFileError(dict->pdf, "Unsupported PNG color type %u.", color_type);
return (NULL);
}
if ((color_type == _PDFIO_PNG_TYPE_GRAY && bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8 && bit_depth != 16) ||
(color_type == _PDFIO_PNG_TYPE_RGB && bit_depth != 8 && bit_depth != 16) ||
(color_type == _PDFIO_PNG_TYPE_INDEXED && bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8))
{
_pdfioFileError(dict->pdf, "Unsupported PNG bit depth %u for color type %u.", bit_depth, color_type);
return (NULL);
}
if (buffer[10] != _PDFIO_PNG_COMPRESSION_FLATE)
{
_pdfioFileError(dict->pdf, "Unsupported PNG compression %u.", buffer[10]);
return (NULL);
}
if (buffer[11] != _PDFIO_PNG_FILTER_ADAPTIVE)
{
_pdfioFileError(dict->pdf, "Unsupported PNG filtering %u.", buffer[11]);
return (NULL);
}
interlace = buffer[12];
if (interlace != _PDFIO_PNG_INTERLACE_NONE)
{
_pdfioFileError(dict->pdf, "Unsupported PNG interlacing %u.", interlace);
return (NULL);
}
num_colors = color_type == _PDFIO_PNG_TYPE_RGB ? 3 : 1;
pdfioDictSetNumber(dict, "Width", width);
pdfioDictSetNumber(dict, "Height", height);
pdfioDictSetNumber(dict, "BitsPerComponent", bit_depth);
@ -2748,7 +2850,7 @@ copy_png(pdfio_dict_t *dict, // I - Dictionary
return (NULL);
pdfioDictSetNumber(decode, "BitsPerComponent", bit_depth);
pdfioDictSetNumber(decode, "Colors", color_type == _PDFIO_PNG_TYPE_RGB ? 3 : 1);
pdfioDictSetNumber(decode, "Colors", num_colors);
pdfioDictSetNumber(decode, "Columns", width);
pdfioDictSetNumber(decode, "Predictor", _PDFIO_PREDICTOR_PNG_AUTO);
pdfioDictSetDict(dict, "DecodeParms", decode);
@ -2948,6 +3050,7 @@ copy_png(pdfio_dict_t *dict, // I - Dictionary
}
return (NULL);
#endif // HAVE_LIBPNG
}
@ -3227,6 +3330,210 @@ create_cp1252(pdfio_file_t *pdf) // I - PDF file
}
//
// 'create_image()' - Create an image object from some data.
//
static pdfio_obj_t * // O - PDF object or `NULL` on error
create_image(
pdfio_dict_t *dict, // I - Image dictionary
const unsigned char *data, // I - Image data
size_t width, // I - Width in columns
size_t height, // I - Height in lines
size_t depth, // I - Bit depth
size_t num_colors, // I - Number of colors
bool alpha) // I - `true` if there is transparency
{
pdfio_file_t *pdf = dict->pdf;
// PDF file
pdfio_dict_t *mask_dict, // Mask image dictionary
*decode; // DecodeParms dictionary
pdfio_obj_t *obj, // Image object
*mask_obj = NULL;
// Mask image object, if any
pdfio_stream_t *st; // Image stream
size_t x, y, // X and Y position in image
bpc = depth / 8,// Bytes per component
bpp = num_colors * bpc,
// Bytes per pixel (less alpha)
linelen; // Line length
const unsigned char *dataptr; // Pointer into image data
unsigned char *line = NULL, // Current line
*lineptr; // Pointer into line
// Allocate memory for one line of data...
linelen = (width * num_colors * depth + 7) / 8;
if ((line = malloc(linelen)) == NULL)
return (NULL);
// Use Flate compression...
pdfioDictSetName(dict, "Filter", "FlateDecode");
// Generate a mask image, as needed...
if (alpha)
{
// Create the image mask dictionary...
if ((mask_dict = pdfioDictCopy(pdf, dict)) == NULL)
{
free(line);
return (NULL);
}
// Transparency masks are always grayscale...
pdfioDictSetName(mask_dict, "ColorSpace", "DeviceGray");
// Set the automatic PNG predictor to optimize compression...
if ((decode = pdfioDictCreate(pdf)) == NULL)
{
free(line);
return (NULL);
}
pdfioDictSetNumber(decode, "BitsPerComponent", depth);
pdfioDictSetNumber(decode, "Colors", 1);
pdfioDictSetNumber(decode, "Columns", width);
pdfioDictSetNumber(decode, "Predictor", _PDFIO_PREDICTOR_PNG_AUTO);
pdfioDictSetDict(mask_dict, "DecodeParms", decode);
// Create the mask object and write the mask image...
if ((mask_obj = pdfioFileCreateObj(pdf, mask_dict)) == NULL)
{
free(line);
return (NULL);
}
if ((st = pdfioObjCreateStream(mask_obj, PDFIO_FILTER_FLATE)) == NULL)
{
free(line);
pdfioObjClose(mask_obj);
return (NULL);
}
for (y = height, dataptr = data + bpp; y > 0; y --)
{
if (bpc == 1)
{
for (x = width, lineptr = line; x > 0; x --, dataptr += bpp)
*lineptr++ = *dataptr++;
}
else
{
for (x = width, lineptr = line; x > 0; x --, dataptr += bpp)
{
*lineptr++ = *dataptr++;
*lineptr++ = *dataptr++;
}
}
pdfioStreamWrite(st, line, width * bpc);
}
pdfioStreamClose(st);
// Use the transparency mask...
pdfioDictSetObj(dict, "SMask", mask_obj);
}
// Set the automatic PNG predictor to optimize compression...
if ((decode = pdfioDictCreate(pdf)) == NULL)
{
free(line);
return (NULL);
}
pdfioDictSetNumber(decode, "BitsPerComponent", depth);
pdfioDictSetNumber(decode, "Colors", num_colors);
pdfioDictSetNumber(decode, "Columns", width);
pdfioDictSetNumber(decode, "Predictor", _PDFIO_PREDICTOR_PNG_AUTO);
pdfioDictSetDict(dict, "DecodeParms", decode);
// Now create the image...
if ((obj = pdfioFileCreateObj(pdf, dict)) == NULL)
{
free(line);
return (NULL);
}
if ((st = pdfioObjCreateStream(obj, PDFIO_FILTER_FLATE)) == NULL)
{
free(line);
pdfioObjClose(obj);
return (NULL);
}
for (y = height, dataptr = data; y > 0; y --)
{
if (alpha)
{
if (bpp == 1)
{
for (x = width, lineptr = line; x > 0; x --, dataptr += bpc)
*lineptr++ = *dataptr++;
}
else
{
for (x = width, lineptr = line; x > 0; x --, dataptr += bpp + bpc, lineptr += bpp)
memcpy(lineptr, dataptr, bpp);
}
pdfioStreamWrite(st, line, linelen);
}
else
{
pdfioStreamWrite(st, dataptr, linelen);
dataptr += linelen;
}
}
free(line);
pdfioStreamClose(st);
return (obj);
}
#ifdef HAVE_LIBPNG
//
// 'png_error_func()' - PNG error message function.
//
static void
png_error_func(
png_structp pp, // I - PNG pointer
png_const_charp message) // I - Error message
{
pdfio_file_t *pdf = (pdfio_file_t *)png_get_error_ptr(pp);
// PDF file
_pdfioFileError(pdf, "Unable to create image object from PNG file: %s", message);
}
//
// 'png_read_func()' - Read from a PNG file.
//
static void
png_read_func(png_structp pp, // I - PNG pointer
png_bytep data, // I - Read buffer
size_t length) // I - Number of bytes to read
{
int *fd = (int *)png_get_io_ptr(pp);
// Pointer to file descriptor
ssize_t bytes; // Bytes read
PDFIO_DEBUG("png_read_func(pp=%p, data=%p, length=%lu)\n", (void *)pp, (void *)data, (unsigned long)length);
if ((bytes = read(*fd, data, length)) < (ssize_t)length)
png_error(pp, "Unable to read from PNG file.");
}
#endif // HAVE_LIBPNG
//
// 'ttf_error_cb()' - Relay a message from the TTF functions.
//
@ -3239,6 +3546,7 @@ ttf_error_cb(pdfio_file_t *pdf, // I - PDF file
}
#ifndef HAVE_LIBPNG
//
// 'update_png_crc()' - Update the CRC-32 value for a PNG chunk.
//
@ -3258,6 +3566,7 @@ update_png_crc(
return (crc);
}
#endif // !HAVE_LIBPNG
//

View File

@ -172,6 +172,8 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="packages\libpng_native.redist.1.6.30\build\native\libpng_native.redist.targets" Condition="Exists('packages\libpng_native.redist.1.6.30\build\native\libpng_native.redist.targets')" />
<Import Project="packages\libpng_native.1.6.30\build\native\libpng_native.targets" Condition="Exists('packages\libpng_native.1.6.30\build\native\libpng_native.targets')" />
<Import Project="packages\zlib_native.redist.1.2.11\build\native\zlib_native.redist.targets" Condition="Exists('packages\zlib_native.redist.1.2.11\build\native\zlib_native.redist.targets')" />
<Import Project="packages\zlib_native.1.2.11\build\native\zlib_native.targets" Condition="Exists('packages\zlib_native.1.2.11\build\native\zlib_native.targets')" />
</ImportGroup>

View File

@ -3,7 +3,7 @@
<metadata>
<id>pdfio_native</id>
<title>PDFio Library for VS2019+</title>
<version>1.4.1</version>
<version>1.5.0</version>
<authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
@ -16,7 +16,7 @@
<copyright>Copyright © 2019-2025 by Michael R Sweet</copyright>
<tags>pdf file native</tags>
<dependencies>
<dependency id="pdfio_native.redist" version="1.4.1" />
<dependency id="pdfio_native.redist" version="1.5.0" />
<dependency id="zlib_native.redist" version="1.2.11" />
</dependencies>
</metadata>

View File

@ -3,7 +3,7 @@
<metadata>
<id>pdfio_native.redist</id>
<title>PDFio Library for VS2019+</title>
<version>1.4.1</version>
<version>1.5.0</version>
<authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>

View File

@ -0,0 +1,9 @@
PngSuite
--------
Permission to use, copy, modify and distribute these images for any
purpose and without fee is hereby granted.
(c) Willem van Schaik, 1996, 2011

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -47,7 +47,7 @@ static int write_header_footer(pdfio_stream_t *st, const char *title, int number
static pdfio_obj_t *write_image_object(pdfio_file_t *pdf, _pdfio_predictor_t predictor);
static int write_images_test(pdfio_file_t *pdf, int number, pdfio_obj_t *font);
static int write_jpeg_test(pdfio_file_t *pdf, const char *title, int number, pdfio_obj_t *font, pdfio_obj_t *image);
static int write_png_test(pdfio_file_t *pdf, int number, pdfio_obj_t *font);
static int write_png_tests(pdfio_file_t *pdf, int number, pdfio_obj_t *font);
static int write_text_test(pdfio_file_t *pdf, int first_page, pdfio_obj_t *font, const char *filename);
static int write_unit_file(pdfio_file_t *inpdf, const char *outname, pdfio_file_t *outpdf, size_t *num_pages, size_t *first_image);
@ -2989,19 +2989,84 @@ write_jpeg_test(pdfio_file_t *pdf, // I - PDF file
//
// 'write_png_test()' - Write a page of PNG test images.
// 'write_png_tests()' - Write pages of PNG test images.
//
static int // O - 0 on success, 1 on failure
write_png_test(pdfio_file_t *pdf, // I - PDF file
int number, // I - Page number
pdfio_obj_t *font) // I - Page number font
write_png_tests(pdfio_file_t *pdf, // I - PDF file
int number, // I - Page number
pdfio_obj_t *font) // I - Page number font
{
pdfio_dict_t *dict; // Page dictionary
pdfio_stream_t *st; // Page contents stream
pdfio_obj_t *color, // pdfio-color.png
*gray, // pdfio-gray.png
*indexed; // pdfio-indexed.png
#ifdef HAVE_LIBPNG
size_t i; // Looping var
char imgname[32]; // Image name
pdfio_obj_t *pngsuite[80]; // PngSuite test file objects
static const char * const pngsuite_files[80] =
{ // PngSuite test filenames
"testfiles/pngsuite/basi0g01.png", "testfiles/pngsuite/basi0g02.png",
"testfiles/pngsuite/basi0g04.png", "testfiles/pngsuite/basi0g08.png",
"testfiles/pngsuite/basi2c08.png", "testfiles/pngsuite/basi3p01.png",
"testfiles/pngsuite/basi3p02.png", "testfiles/pngsuite/basi3p04.png",
"testfiles/pngsuite/basi3p08.png", "testfiles/pngsuite/basi4a08.png",
"testfiles/pngsuite/basi6a08.png", "testfiles/pngsuite/basn0g01.png",
"testfiles/pngsuite/basn0g02.png", "testfiles/pngsuite/basn0g04.png",
"testfiles/pngsuite/basn0g08.png", "testfiles/pngsuite/basn2c08.png",
"testfiles/pngsuite/basn3p01.png", "testfiles/pngsuite/basn3p02.png",
"testfiles/pngsuite/basn3p04.png", "testfiles/pngsuite/basn3p08.png",
"testfiles/pngsuite/basn4a08.png", "testfiles/pngsuite/basn6a08.png",
"testfiles/pngsuite/exif2c08.png", "testfiles/pngsuite/g03n2c08.png",
"testfiles/pngsuite/g03n3p04.png", "testfiles/pngsuite/g04n2c08.png",
"testfiles/pngsuite/g04n3p04.png", "testfiles/pngsuite/g05n2c08.png",
"testfiles/pngsuite/g05n3p04.png", "testfiles/pngsuite/g07n2c08.png",
"testfiles/pngsuite/g07n3p04.png", "testfiles/pngsuite/g10n2c08.png",
"testfiles/pngsuite/g10n3p04.png", "testfiles/pngsuite/g25n2c08.png",
"testfiles/pngsuite/g25n3p04.png", "testfiles/pngsuite/s02i3p01.png",
"testfiles/pngsuite/s02n3p01.png", "testfiles/pngsuite/s03i3p01.png",
"testfiles/pngsuite/s03n3p01.png", "testfiles/pngsuite/s04i3p01.png",
"testfiles/pngsuite/s04n3p01.png", "testfiles/pngsuite/s05i3p02.png",
"testfiles/pngsuite/s05n3p02.png", "testfiles/pngsuite/s06i3p02.png",
"testfiles/pngsuite/s06n3p02.png", "testfiles/pngsuite/s07i3p02.png",
"testfiles/pngsuite/s07n3p02.png", "testfiles/pngsuite/s08i3p02.png",
"testfiles/pngsuite/s08n3p02.png", "testfiles/pngsuite/s09i3p02.png",
"testfiles/pngsuite/s09n3p02.png", "testfiles/pngsuite/s32i3p04.png",
"testfiles/pngsuite/s32n3p04.png", "testfiles/pngsuite/s33i3p04.png",
"testfiles/pngsuite/s33n3p04.png", "testfiles/pngsuite/s34i3p04.png",
"testfiles/pngsuite/s34n3p04.png", "testfiles/pngsuite/s35i3p04.png",
"testfiles/pngsuite/s35n3p04.png", "testfiles/pngsuite/s36i3p04.png",
"testfiles/pngsuite/s36n3p04.png", "testfiles/pngsuite/s37i3p04.png",
"testfiles/pngsuite/s37n3p04.png", "testfiles/pngsuite/s38i3p04.png",
"testfiles/pngsuite/s38n3p04.png", "testfiles/pngsuite/s39i3p04.png",
"testfiles/pngsuite/s39n3p04.png", "testfiles/pngsuite/s40i3p04.png",
"testfiles/pngsuite/s40n3p04.png", "testfiles/pngsuite/tbbn0g04.png",
"testfiles/pngsuite/tbbn3p08.png", "testfiles/pngsuite/tbgn3p08.png",
"testfiles/pngsuite/tbrn2c08.png", "testfiles/pngsuite/tbwn3p08.png",
"testfiles/pngsuite/tbyn3p08.png", "testfiles/pngsuite/tm3n3p02.png",
"testfiles/pngsuite/tp0n0g08.png", "testfiles/pngsuite/tp0n2c08.png",
"testfiles/pngsuite/tp0n3p08.png", "testfiles/pngsuite/tp1n3p08.png"
};
static const char * const pngsuite_labels[80] =
{ // PngSuite test labels
"basi0g01", "basi0g02", "basi0g04", "basi0g08", "basi2c08", "basi3p01",
"basi3p02", "basi3p04", "basi3p08", "basi4a08", "basi6a08", "basn0g01",
"basn0g02", "basn0g04", "basn0g08", "basn2c08", "basn3p01", "basn3p02",
"basn3p04", "basn3p08", "basn4a08", "basn6a08", "exif2c08", "g03n2c08",
"g03n3p04", "g04n2c08", "g04n3p04", "g05n2c08", "g05n3p04", "g07n2c08",
"g07n3p04", "g10n2c08", "g10n3p04", "g25n2c08", "g25n3p04", "s02i3p01",
"s02n3p01", "s03i3p01", "s03n3p01", "s04i3p01", "s04n3p01", "s05i3p02",
"s05n3p02", "s06i3p02", "s06n3p02", "s07i3p02", "s07n3p02", "s08i3p02",
"s08n3p02", "s09i3p02", "s09n3p02", "s32i3p04", "s32n3p04", "s33i3p04",
"s33n3p04", "s34i3p04", "s34n3p04", "s35i3p04", "s35n3p04", "s36i3p04",
"s36n3p04", "s37i3p04", "s37n3p04", "s38i3p04", "s38n3p04", "s39i3p04",
"s39n3p04", "s40i3p04", "s40n3p04", "tbbn0g04", "tbbn3p08", "tbgn3p08",
"tbrn2c08", "tbwn3p08", "tbyn3p08", "tm3n3p02", "tp0n0g08", "tp0n2c08",
"tp0n3p08", "tp1n3p08"
};
#endif // HAVE_LIBPNG
// Import the PNG test images
@ -3023,6 +3088,7 @@ write_png_test(pdfio_file_t *pdf, // I - PDF file
else
return (1);
////// PDFio PNG image test page...
// Create the page dictionary, object, and stream...
fputs("pdfioDictCreate: ", stdout);
if ((dict = pdfioDictCreate(pdf)) != NULL)
@ -3168,6 +3234,109 @@ write_png_test(pdfio_file_t *pdf, // I - PDF file
else
return (1);
#ifdef HAVE_LIBPNG
////// PngSuite page
// Create the image objects...
for (i = 0; i < (sizeof(pngsuite_files) / sizeof(pngsuite_files[0])); i ++)
{
fprintf(stdout, "pdfioFileCreateImageObjFromFile(\"%s\"): ", pngsuite_files[i]);
if ((pngsuite[i] = pdfioFileCreateImageObjFromFile(pdf, pngsuite_files[i], false)) != NULL)
puts("PASS");
else
return (1);
}
// Create the page dictionary, object, and stream...
fputs("pdfioDictCreate: ", stdout);
if ((dict = pdfioDictCreate(pdf)) != NULL)
puts("PASS");
else
return (1);
for (i = 0; i < (sizeof(pngsuite_files) / sizeof(pngsuite_files[0])); i ++)
{
fprintf(stdout, "pdfioPageDictAddImage(\"%s\"): ", pngsuite_labels[i]);
snprintf(imgname, sizeof(imgname), "IM%u", (unsigned)(i + 1));
if (pdfioPageDictAddImage(dict, pdfioStringCreate(pdf, imgname), pngsuite[i]))
puts("PASS");
else
return (1);
}
fputs("pdfioPageDictAddFont(F1): ", stdout);
if (pdfioPageDictAddFont(dict, "F1", font))
puts("PASS");
else
return (1);
printf("pdfioFileCreatePage(%d): ", number + 1);
if ((st = pdfioFileCreatePage(pdf, dict)) != NULL)
puts("PASS");
else
return (1);
if (write_header_footer(st, "PngSuite Test Page", number + 1))
goto error;
// Show content...
fputs("pdfioContentSetTextFont(\"F1\", 9.0): ", stdout);
if (pdfioContentSetTextFont(st, "F1", 8.0))
puts("PASS");
else
goto error;
for (i = 0; i < (sizeof(pngsuite_files) / sizeof(pngsuite_files[0])); i ++)
{
double x = (i % 8) * 69.0 + 36; // X position
double y = 671 - (i / 8) * 64.0; // Y position
fputs("pdfioContentTextBegin(): ", stdout);
if (pdfioContentTextBegin(st))
puts("PASS");
else
goto error;
printf("pdfioContentTextMoveTo(%g, %g): ", x, y);
if (pdfioContentTextMoveTo(st, x, y))
puts("PASS");
else
goto error;
printf("pdfioContentTextShow(\"%s\"): ", pngsuite_labels[i]);
if (pdfioContentTextShow(st, false, pngsuite_labels[i]))
puts("PASS");
else
goto error;
fputs("pdfioContentTextEnd(): ", stdout);
if (pdfioContentTextEnd(st))
puts("PASS");
else
goto error;
}
for (i = 0; i < (sizeof(pngsuite_files) / sizeof(pngsuite_files[0])); i ++)
{
double x = (i % 8) * 69.0 + 36; // X position
double y = 671 - (i / 8) * 64.0; // Y position
snprintf(imgname, sizeof(imgname), "IM%u", (unsigned)(i + 1));
printf("pdfioContentDrawImage(\"%s\"): ", imgname);
if (pdfioContentDrawImage(st, imgname, x, y + 9, 32, 32))
puts("PASS");
else
goto error;
}
// Close the object and stream...
fputs("pdfioStreamClose: ", stdout);
if (pdfioStreamClose(st))
puts("PASS");
else
return (1);
#endif // HAVE_LIBPNG
return (0);
error:
@ -3367,6 +3536,7 @@ write_unit_file(
*gray_jpg, // gray.jpg image
*helvetica, // Helvetica font
*page; // Page from test PDF file
int pagenum = 1; // Current page number
pdfio_dict_t *catalog; // Catalog dictionary
@ -3506,10 +3676,14 @@ write_unit_file(
else
return (1);
pagenum ++;
// Write a page with a color image...
if (write_jpeg_test(outpdf, "Color JPEG Test", 2, helvetica, color_jpg))
if (write_jpeg_test(outpdf, "Color JPEG Test", pagenum, helvetica, color_jpg))
return (1);
pagenum ++;
// Copy the third page from the test PDF file...
fputs("pdfioFileGetPage(2): ", stdout);
if ((page = pdfioFileGetPage(inpdf, 2)) != NULL)
@ -3523,39 +3697,60 @@ write_unit_file(
else
return (1);
pagenum ++;
// Write a page with a grayscale image...
if (write_jpeg_test(outpdf, "Grayscale JPEG Test", 4, helvetica, gray_jpg))
if (write_jpeg_test(outpdf, "Grayscale JPEG Test", pagenum, helvetica, gray_jpg))
return (1);
pagenum ++;
// Write a page with PNG images...
if (write_png_test(outpdf, 5, helvetica))
if (write_png_tests(outpdf, pagenum, helvetica))
return (1);
#ifdef HAVE_LIBPNG
pagenum += 2;
#else
pagenum ++;
#endif // HAVE_LIBPNG
// Write a page that tests multiple color spaces...
if (write_color_test(outpdf, 6, helvetica))
if (write_color_test(outpdf, pagenum, helvetica))
return (1);
pagenum ++;
// Write a page with test images...
*first_image = pdfioFileGetNumObjs(outpdf) + 1;
if (write_images_test(outpdf, 7, helvetica))
if (write_images_test(outpdf, pagenum, helvetica))
return (1);
pagenum ++;
// Write a page width alpha (soft masks)...
if (write_alpha_test(outpdf, 8, helvetica))
if (write_alpha_test(outpdf, pagenum, helvetica))
return (1);
pagenum ++;
// Test TrueType fonts...
if (write_font_test(outpdf, 9, helvetica, "testfiles/OpenSans-Regular.ttf", false))
if (write_font_test(outpdf, pagenum, helvetica, "testfiles/OpenSans-Regular.ttf", false))
return (1);
if (write_font_test(outpdf, 10, helvetica, "testfiles/OpenSans-Regular.ttf", true))
pagenum ++;
if (write_font_test(outpdf, pagenum, helvetica, "testfiles/OpenSans-Regular.ttf", true))
return (1);
if (write_font_test(outpdf, 11, helvetica, "testfiles/NotoSansJP-Regular.otf", true))
pagenum ++;
if (write_font_test(outpdf, pagenum, helvetica, "testfiles/NotoSansJP-Regular.otf", true))
return (1);
pagenum ++;
// Print this text file...
if (write_text_test(outpdf, 12, helvetica, "README.md"))
if (write_text_test(outpdf, pagenum, helvetica, "README.md"))
return (1);
fputs("pdfioFileGetNumPages: ", stdout);

View File

@ -153,6 +153,8 @@
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="packages\libpng_native.redist.1.6.30\build\native\libpng_native.redist.targets" Condition="Exists('packages\libpng_native.redist.1.6.30\build\native\libpng_native.redist.targets')" />
<Import Project="packages\libpng_native.1.6.30\build\native\libpng_native.targets" Condition="Exists('packages\libpng_native.1.6.30\build\native\libpng_native.targets')" />
<Import Project="packages\zlib_native.redist.1.2.11\build\native\zlib_native.redist.targets" Condition="Exists('packages\zlib_native.redist.1.2.11\build\native\zlib_native.redist.targets')" />
<Import Project="packages\zlib_native.1.2.11\build\native\zlib_native.targets" Condition="Exists('packages\zlib_native.1.2.11\build\native\zlib_native.targets')" />
</ImportGroup>