Implement WebP image support (Issue #144)

This commit is contained in:
Michael R Sweet
2026-01-18 16:49:26 -05:00
parent 61d7e0c68d
commit ddb57bb754
14 changed files with 556 additions and 30 deletions

View File

@@ -10,6 +10,7 @@ v1.7.0 - YYYY-MM-DD
(Issue #11)
- Added support for LZWDecode filters (Issue #11)
- Added support for GIF files (Issue #145)
- Added support for WebP files (Issue #144)
- Added `pdfioPageGetXxx` functions to get values from the page dictionaries
(Issue #150)
- Fixed a buffer overflow in the (still not enabled) AES-256 code.

View File

@@ -28,8 +28,12 @@ PDFio requires the following to build the software:
- A C99 compiler such as Clang, GCC, or MS Visual C
- A POSIX-compliant `make` program
- LIBPNG (1.6 or later) for full PNG image support (optional)
- ZLIB (1.1 or later)
- A POSIX-compliant `sh` program
- libpng (<https://www.libpng.org/>) 1.6 or later for full PNG image support
(optional)
- libwebp (<https://developers.google.com/speed/webp>) 1.0 or later for WebP
image support (optional)
- ZLIB (<https://www.zlib.net/>) 1.1 or later
IDE files for Xcode (macOS/iOS) and Visual Studio (Windows) are also provided.

50
configure vendored
View File

@@ -734,6 +734,7 @@ ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_libpng
enable_libwebp
enable_static
enable_shared
enable_debug
@@ -1372,7 +1373,9 @@ 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,
--disable-libpng use libpng for pdfioFileCreateImageObjFromFile,
default=auto
--disable-libwebp use libwebp for pdfioFileCreateImageObjFromFile,
default=auto
--disable-static do not install static library
--enable-shared install shared library
@@ -4301,6 +4304,51 @@ then :
fi
# Check whether --enable-libwebp was given.
if test ${enable_libwebp+y}
then :
enableval=$enable_libwebp;
fi
if test "x$PKGCONFIG" != x -a x$enable_libwebp != xno
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libwebp" >&5
printf %s "checking for libwebp... " >&6; }
if $PKGCONFIG --exists libwebp
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; };
printf "%s\n" "#define HAVE_LIBWEBP 1" >>confdefs.h
CPPFLAGS="$($PKGCONFIG --cflags libwebp) -DHAVE_LIBWEBP=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libwebp) -lz $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="libwebp, $PKGCONFIG_REQUIRES_PRIVATE"
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; };
if test x$enable_libwebp = xyes
then :
as_fn_error $? "libwebp-dev required for --enable-libwebp." "$LINENO" 5
fi
fi
elif test x$enable_libwebp = xyes
then :
as_fn_error $? "libwebp-dev required for --enable-libwebp." "$LINENO" 5
fi
# Check whether --enable-static was given.
if test ${enable_static+y}
then :

View File

@@ -1,7 +1,7 @@
dnl
dnl Configuration script for PDFio
dnl
dnl Copyright © 2023-2025 by Michael R Sweet
dnl Copyright © 2023-2026 by Michael R Sweet
dnl
dnl Licensed under Apache License v2.0. See the file "LICENSE" for more
dnl information.
@@ -168,7 +168,7 @@ AS_IF([$PKGCONFIG --exists zlib], [
dnl libpng...
AC_ARG_ENABLE([libpng], AS_HELP_STRING([--enable-libpng], [use libpng for pdfioFileCreateImageObjFromFile, default=auto]))
AC_ARG_ENABLE([libpng], AS_HELP_STRING([--disable-libpng], [use libpng for pdfioFileCreateImageObjFromFile, default=auto]))
AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
AC_MSG_CHECKING([for libpng-1.6.x])
@@ -189,6 +189,28 @@ AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
])
dnl libwebp...
AC_ARG_ENABLE([libwebp], AS_HELP_STRING([--disable-libwebp], [use libwebp for pdfioFileCreateImageObjFromFile, default=auto]))
AS_IF([test "x$PKGCONFIG" != x -a x$enable_libwebp != xno], [
AC_MSG_CHECKING([for libwebp])
AS_IF([$PKGCONFIG --exists libwebp], [
AC_MSG_RESULT([yes]);
AC_DEFINE([HAVE_LIBWEBP], 1, [Have WebP library?])
CPPFLAGS="$($PKGCONFIG --cflags libwebp) -DHAVE_LIBWEBP=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libwebp) -lz $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="libwebp, $PKGCONFIG_REQUIRES_PRIVATE"
], [
AC_MSG_RESULT([no]);
AS_IF([test x$enable_libwebp = xyes], [
AC_MSG_ERROR([libwebp-dev required for --enable-libwebp.])
])
])
], [test x$enable_libwebp = xyes], [
AC_MSG_ERROR([libwebp-dev required for --enable-libwebp.])
])
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]))

View File

@@ -52,11 +52,17 @@ A POSIX\-compliant sh program
.IP \(bu 5
.PP
ZLIB (https://www.zlib.net/) 1.0 or higher
libpng (https://www.libpng.org/) 1.6 or later for full PNG image support (optional)
.IP \(bu 5
.PP
PDFio will also use libpng 1.6 or higher (https://www.libpng.org/) to provide enhanced PNG image support.
libwebp (https://developers.google.com/speed/webp) 1.0 or later for WebP image support (optional)
.IP \(bu 5
.PP
ZLIB (https://www.zlib.net/) 1.1 or later
.PP
IDE files for Xcode (macOS/iOS) and Visual Studio (Windows) are also provided.
.SS Installing PDFio
@@ -771,7 +777,7 @@ will create an object for a 1024x1024 RGBA image in memory, using the default co
.PP
The "interpolate" argument specifies whether the colors in the image should be smoothed/interpolated when scaling. This is most useful for photographs but should be false for screenshot and barcode images.
.PP
If you have a GIF, JPEG, or PNG file, use the pdfioFileCreateImageObjFromFile function to copy the image into a PDF image object, for example:
If you have a GIF, JPEG, PNG, or WebP file, use the pdfioFileCreateImageObjFromFile function to copy the image into a PDF image object, for example:
.nf
pdfio_file_t *pdf = pdfioFileCreate(...);
@@ -4187,10 +4193,10 @@ pdfio_obj_t * pdfioFileCreateImageObjFromFile (
);
.fi
.PP
This function creates an image object in a PDF file from a GIF, JPEG, or PNG
file. The "filename" parameter specifies the name of the GIF, JPEG, or PNG
file, while the "interpolate" parameter specifies whether to interpolate when
scaling the image on the page.
This function creates an image object in a PDF file from a GIF, JPEG, PNG, or
WebP file. The "filename" parameter specifies the name of the GIF, JPEG,
PNG, or WebP file, while the "interpolate" parameter specifies whether to
interpolate when scaling the image on the page.
.PP
.IP 5
Note: PNG files containing transparency cannot be used when producing

View File

@@ -570,10 +570,13 @@ span.string {
</li>
<li><p>A POSIX-compliant <code>sh</code> program</p>
</li>
<li><p>ZLIB (<a href="https://www.zlib.net/">https://www.zlib.net/</a>) 1.0 or higher</p>
<li><p>libpng (<a href="https://www.libpng.org/">https://www.libpng.org/</a>) 1.6 or later for full PNG image support (optional)</p>
</li>
<li><p>libwebp (<a href="https://developers.google.com/speed/webp">https://developers.google.com/speed/webp</a>) 1.0 or later for WebP image support (optional)</p>
</li>
<li><p>ZLIB (<a href="https://www.zlib.net/">https://www.zlib.net/</a>) 1.1 or later</p>
</li>
</ul>
<p>PDFio will also use libpng 1.6 or higher (<a href="https://www.libpng.org/">https://www.libpng.org/</a>) to provide enhanced PNG image support.</p>
<p>IDE files for Xcode (macOS/iOS) and Visual Studio (Windows) are also provided.</p>
<h3 class="title" id="installing-pdfio">Installing PDFio</h3>
<p>PDFio comes with a configure script that creates a portable makefile that will work on any POSIX-compliant system with ZLIB installed. To make it, run:</p>
@@ -1046,7 +1049,7 @@ pdfio_obj_t *img =
<span class="comment">/*alpha*/</span><span class="reserved">true</span>, <span class="comment">/*interpolate*/</span><span class="reserved">false</span>);
</code></pre>
<p>The &quot;interpolate&quot; argument specifies whether the colors in the image should be smoothed/interpolated when scaling. This is most useful for photographs but should be <code>false</code> for screenshot and barcode images.</p>
<p>If you have a GIF, JPEG, or PNG file, use the <a href="#pdfioFileCreateImageObjFromFile"><code>pdfioFileCreateImageObjFromFile</code></a> function to copy the image into a PDF image object, for example:</p>
<p>If you have a GIF, JPEG, PNG, or WebP file, use the <a href="#pdfioFileCreateImageObjFromFile"><code>pdfioFileCreateImageObjFromFile</code></a> function to copy the image into a PDF image object, for example:</p>
<pre><code class="language-c">pdfio_file_t *pdf = pdfioFileCreate(...);
pdfio_obj_t *img =
pdfioFileCreateImageObjFromFile(pdf, <span class="string">&quot;myphoto.jpg&quot;</span>, <span class="comment">/*interpolate*/</span><span class="reserved">true</span>);
@@ -4480,10 +4483,10 @@ files do not support alpha-based transparency.</blockquote>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Object</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function creates an image object in a PDF file from a GIF, JPEG, or PNG
file. The &quot;filename&quot; parameter specifies the name of the GIF, JPEG, or PNG
file, while the &quot;interpolate&quot; parameter specifies whether to interpolate when
scaling the image on the page.<br>
<p class="discussion">This function creates an image object in a PDF file from a GIF, JPEG, PNG, or
WebP file. The &quot;filename&quot; parameter specifies the name of the GIF, JPEG,
PNG, or WebP file, while the &quot;interpolate&quot; parameter specifies whether to
interpolate when scaling the image on the page.<br>
<br>
</p><blockquote>
Note: PNG files containing transparency cannot be used when producing

View File

@@ -28,10 +28,11 @@ PDFio requires the following to build the software:
- A C99 compiler such as Clang, GCC, or MS Visual C
- A POSIX-compliant `make` program
- A POSIX-compliant `sh` program
- ZLIB (<https://www.zlib.net/>) 1.0 or higher
PDFio will also use libpng 1.6 or higher (<https://www.libpng.org/>) to provide
enhanced PNG image support.
- libpng (<https://www.libpng.org/>) 1.6 or later for full PNG image support
(optional)
- libwebp (<https://developers.google.com/speed/webp>) 1.0 or later for WebP
image support (optional)
- ZLIB (<https://www.zlib.net/>) 1.1 or later
IDE files for Xcode (macOS/iOS) and Visual Studio (Windows) are also provided.
@@ -752,7 +753,7 @@ The "interpolate" argument specifies whether the colors in the image should be
smoothed/interpolated when scaling. This is most useful for photographs but
should be `false` for screenshot and barcode images.
If you have a GIF, JPEG, or PNG file, use the
If you have a GIF, JPEG, PNG, or WebP file, use the
[`pdfioFileCreateImageObjFromFile`](@@) function to copy the image into a PDF
image object, for example:

View File

@@ -12,9 +12,13 @@
#include "pdfio-base-font-widths.h"
#include "pdfio-cgats001-compat.h"
#include "ttf.h"
#include <sys/stat.h>
#ifdef HAVE_LIBPNG
# include <png.h>
#endif // HAVE_LIBPNG
#ifdef HAVE_LIBWEBP
# include <webp/decode.h>
#endif // HAVE_LIBWEBP
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846264338327950288
@@ -91,6 +95,9 @@ typedef pdfio_obj_t *(*_pdfio_image_func_t)(pdfio_dict_t *dict, int fd);
static pdfio_obj_t *copy_gif(pdfio_dict_t *dict, int fd);
static pdfio_obj_t *copy_jpeg(pdfio_dict_t *dict, int fd);
static pdfio_obj_t *copy_png(pdfio_dict_t *dict, int fd);
#ifdef HAVE_LIBWEBP
static pdfio_obj_t *copy_webp(pdfio_dict_t *dict, int fd);
#endif // HAVE_LIBWEBP
static bool create_cp1252(pdfio_file_t *pdf);
static pdfio_obj_t *create_font(pdfio_obj_t *file_obj, ttf_t *font, bool unicode);
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);
@@ -2141,10 +2148,10 @@ pdfioFileCreateImageObjFromData(
//
// 'pdfioFileCreateImageObjFromFile()' - Add an image object to a PDF file from a file.
//
// This function creates an image object in a PDF file from a GIF, JPEG, or PNG
// file. The "filename" parameter specifies the name of the GIF, JPEG, or PNG
// file, while the "interpolate" parameter specifies whether to interpolate when
// scaling the image on the page.
// This function creates an image object in a PDF file from a GIF, JPEG, PNG, or
// WebP file. The "filename" parameter specifies the name of the GIF, JPEG,
// PNG, or WebP file, while the "interpolate" parameter specifies whether to
// interpolate when scaling the image on the page.
//
// > Note: PNG files containing transparency cannot be used when producing
// > PDF/A files. Files containing animation yield the final frame of the
@@ -2201,9 +2208,16 @@ pdfioFileCreateImageObjFromFile(
}
else if (!memcmp(buffer, "\377\330\377", 3))
{
// JPEG image...
// JPEG image...
copy_func = copy_jpeg;
}
#ifdef HAVE_LIBWEBP
else if (!memcmp(buffer, "RIFF", 4) && !memcmp(buffer + 8, "WEBP", 4))
{
// WebP image
copy_func = copy_webp;
}
#endif // HAVE_LIBWEBP
else
{
// Something else that isn't supported...
@@ -2498,6 +2512,7 @@ copy_gif(pdfio_dict_t *dict, // I - Image dictionary
extdesc; // Extension descriptor
uint8_t block[256]; // Extension block
ssize_t blocklen; // Length of block
pdfio_dict_t *decode; // Decode parameters
// Read the header; we already know it is a GIF file...
@@ -2579,6 +2594,19 @@ copy_gif(pdfio_dict_t *dict, // I - Image dictionary
pdfioDictSetArray(dict, "Mask", mask);
}
if ((decode = pdfioDictCreate(dict->pdf)) == NULL)
{
_pdfioFileError(dict->pdf, "Unable to create decode parameters for WebP image.");
goto done;
}
pdfioDictSetNumber(decode, "BitsPerComponent", 8);
pdfioDictSetNumber(decode, "Colors", 1);
pdfioDictSetNumber(decode, "Columns", width);
pdfioDictSetNumber(decode, "Predictor", _PDFIO_PREDICTOR_PNG_AUTO);
pdfioDictSetDict(dict, "DecodeParms", decode);
pdfioDictSetName(dict, "Filter", "FlateDecode");
image_obj = create_image(dict, data, width, height, 8, 1, /*alpha*/false);
goto done;
@@ -3453,6 +3481,86 @@ copy_png(pdfio_dict_t *dict, // I - Dictionary
}
#ifdef HAVE_LIBWEBP
//
// 'copy_webp()' - Copy a WebP image.
//
static pdfio_obj_t * // O - Image object
copy_webp(pdfio_dict_t *dict, // I - Image dictionary
int fd) // I - Image file
{
struct stat finfo; // Image file information
uint8_t *fdata = NULL; // Image file data
int width, // Width of image
height; // Height of image
uint8_t *pixels = NULL; // Image pixel (RGBA) data
pdfio_obj_t *obj = NULL; // Image object
pdfio_dict_t *decode; // Stream decode parameters
if (fstat(fd, &finfo))
{
_pdfioFileError(dict->pdf, "Unable to get WebP file information: %s", strerror(errno));
return (NULL);
}
if (finfo.st_size > (1024 * 1024))
{
_pdfioFileError(dict->pdf, "WebP image is too large.");
goto done;
}
if ((fdata = malloc((size_t)finfo.st_size)) == NULL)
{
_pdfioFileError(dict->pdf, "Unable to allocate memory for WebP file: %s", strerror(errno));
goto done;
}
if (read(fd, fdata, (size_t)finfo.st_size) < (ssize_t)finfo.st_size)
{
_pdfioFileError(dict->pdf, "Unable to read WebP file.");
goto done;
}
if ((pixels = WebPDecodeRGBA(fdata, (size_t)finfo.st_size, &width, &height)) == NULL)
{
_pdfioFileError(dict->pdf, "Invalid WebP file.");
goto done;
}
pdfioDictSetNumber(dict, "Width", width);
pdfioDictSetNumber(dict, "Height", height);
pdfioDictSetNumber(dict, "BitsPerComponent", 8);
pdfioDictSetArray(dict, "ColorSpace", pdfioArrayCreateColorFromStandard(dict->pdf, /*num_colors*/3, PDFIO_CS_SRGB));
pdfioDictSetName(dict, "Filter", "FlateDecode");
if ((decode = pdfioDictCreate(dict->pdf)) == NULL)
{
_pdfioFileError(dict->pdf, "Unable to create decode parameters for WebP image.");
goto done;
}
pdfioDictSetNumber(decode, "BitsPerComponent", 8);
pdfioDictSetNumber(decode, "Colors", 3);
pdfioDictSetNumber(decode, "Columns", width);
pdfioDictSetNumber(decode, "Predictor", _PDFIO_PREDICTOR_PNG_AUTO);
pdfioDictSetDict(dict, "DecodeParms", decode);
obj = create_image(dict, pixels, width, height, /*depth*/8, /*num_colors*/3, /*alpha*/true);
done:
free(fdata);
if (pixels)
WebPFree(pixels);
return (obj);
}
#endif // HAVE_LIBWEBP
//
// 'create_cp1252()' - Create the CP1252 font encoding object.
//

BIN
testfiles/color.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
testfiles/gray.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
testfiles/pdfio-color.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
testfiles/pdfio-gray.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
testfiles/pdfio-rgba.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -60,6 +60,9 @@ static int write_pdfa_file(const char *filename, const char *pdfa_version);
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);
#ifdef HAVE_LIBWEBP
static int write_webp_tests(pdfio_file_t *pdf, int number, pdfio_obj_t *font);
#endif // HAVE_LIBWEBP
//
@@ -5021,6 +5024,14 @@ write_unit_file(
pagenum ++;
#endif // HAVE_LIBPNG
#ifdef HAVE_LIBWEBP
// Write a page with WebP images...
if (write_webp_tests(outpdf, pagenum, helvetica))
return (1);
pagenum ++;
#endif // HAVE_LIBWEBP
// Write a page that tests multiple color spaces...
if (write_color_test(outpdf, pagenum, helvetica))
return (1);
@@ -5085,3 +5096,325 @@ write_unit_file(
return (0);
}
#ifdef HAVE_LIBWEBP
//
// 'write_webp_tests()' - Write pages of WebP test images.
//
static int // O - 0 on success, 1 on failure
write_webp_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
size_t i; // Looping var
pdfio_obj_t *color, // color.gif
*gray, // gray.gif
*pdfio[3]; // pdfio-*.gif
char imgname[32]; // Image name
double x, xt, // X positions
y; // Y position
static const char * const pdfio_files[3] =
{ // PDFIO WebP test filenames
"testfiles/pdfio-color.webp", // No transparency
"testfiles/pdfio-gray.webp", // No transparency
"testfiles/pdfio-rgba.webp" // Transparency
};
static const char * const pdfio_labels[3] =
{ // PDFIO WebP test labels
"pdfio-color",
"pdfio-gray",
"pdfio-rgba"
};
// Import the WebP test images
testBegin("pdfioFileCreateImageObjFromFile(\"testfiles/gray.webp\")");
if ((gray = pdfioFileCreateImageObjFromFile(pdf, "testfiles/gray.webp", false)) != NULL)
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
testBegin("pdfioFileCreateImageObjFromFile(\"testfiles/color.webp\")");
if ((color = pdfioFileCreateImageObjFromFile(pdf, "testfiles/color.webp", false)) != NULL)
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
for (i = 0; i < (sizeof(pdfio_files) / sizeof(pdfio_files[0])); i ++)
{
testBegin("pdfioFileCreateImageObjFromFile(\"%s\")", pdfio_files[i]);
if ((pdfio[i] = pdfioFileCreateImageObjFromFile(pdf, pdfio_files[i], false)) != NULL)
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
}
// Create the page dictionary, object, and stream...
testBegin("pdfioDictCreate");
if ((dict = pdfioDictCreate(pdf)) != NULL)
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
testBegin("pdfioPageDictAddImage(gray)");
if (pdfioPageDictAddImage(dict, "IM1", gray))
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
testBegin("pdfioPageDictAddImage(color)");
if (pdfioPageDictAddImage(dict, "IM2", color))
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
for (i = 0; i < (sizeof(pdfio_files) / sizeof(pdfio_files[0])); i ++)
{
testBegin("pdfioPageDictAddImage(\"%s\")", pdfio_labels[i]);
snprintf(imgname, sizeof(imgname), "IM%u", (unsigned)(i + 11));
if (pdfioPageDictAddImage(dict, pdfioStringCreate(pdf, imgname), pdfio[i]))
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
}
testBegin("pdfioPageDictAddFont(F1)");
if (pdfioPageDictAddFont(dict, "F1", font))
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
testBegin("pdfioFileCreatePage(%d)", number);
if ((st = pdfioFileCreatePage(pdf, dict)) != NULL)
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
if (write_header_footer(st, "WebP Image Test Page", number))
goto error;
// Show content...
testBegin("pdfioContentSetTextFont(\"F1\", 18.0)");
if (pdfioContentSetTextFont(st, "F1", 18.0))
testEnd(true);
else
goto error;
testBegin("pdfioContentTextBegin()");
if (pdfioContentTextBegin(st))
testEnd(true);
else
goto error;
x = 36.0;
xt = x + 0.5 * (216.0 - pdfioContentTextMeasure(font, "gray", 18.0));
y = 360.0;
testBegin("pdfioContentTextMoveTo(%g, %g)", xt, y + 12.0);
if (pdfioContentTextMoveTo(st, xt, y + 12.0))
testEnd(true);
else
goto error;
testBegin("pdfioContentTextShow(\"gray\")");
if (pdfioContentTextShow(st, false, "gray"))
testEnd(true);
else
goto error;
testBegin("pdfioContentTextEnd()");
if (pdfioContentTextEnd(st))
testEnd(true);
else
goto error;
testBegin("pdfioContentDrawImage(\"IM1\")");
if (pdfioContentDrawImage(st, "IM1", x, y + 36, 216, 324))
testEnd(true);
else
goto error;
testBegin("pdfioContentTextBegin()");
if (pdfioContentTextBegin(st))
testEnd(true);
else
goto error;
x = 343.0;
xt = x + 0.5 * (216.0 - pdfioContentTextMeasure(font, "color", 18.0));
testBegin("pdfioContentTextMoveTo(%g, %g)", xt, y + 12.0);
if (pdfioContentTextMoveTo(st, xt, y + 12.0))
testEnd(true);
else
goto error;
testBegin("pdfioContentTextShow(\"color\")");
if (pdfioContentTextShow(st, false, "color"))
testEnd(true);
else
goto error;
testBegin("pdfioContentTextEnd()");
if (pdfioContentTextEnd(st))
testEnd(true);
else
goto error;
testBegin("pdfioContentDrawImage(\"IM2\")");
if (pdfioContentDrawImage(st, "IM2", x, y + 36, 216, 324))
testEnd(true);
else
goto error;
for (i = 0; i < (sizeof(pdfio_labels) / sizeof(pdfio_labels[0])); i ++)
{
x = 36.0 + (i & 3) * (150.0 + 36.0);
y = 342.0 - (1 + i / 3) * (150.0 + 36.0);
testBegin("pdfioContentSetFillColorDeviceRGB(0, 1, 1)");
if (pdfioContentSetFillColorDeviceRGB(st, 0.0, 1.0, 1.0))
testEnd(true);
else
goto error;
testBegin("pdfioContentPathRect(%g, %g, 150, 150)", x, y + 36.0);
if (pdfioContentPathRect(st, x, y + 36.0, 150, 150))
testEnd(true);
else
goto error;
testBegin("pdfioContentFill(false)");
if (pdfioContentFill(st, false))
testEnd(true);
else
goto error;
testBegin("pdfioContentSetFillColorDeviceGray(0.0)");
if (pdfioContentSetFillColorDeviceGray(st, 0.0))
testEnd(true);
else
goto error;
testBegin("pdfioContentTextBegin()");
if (pdfioContentTextBegin(st))
{
testEnd(true);
}
else
{
testEnd(false);
goto error;
}
xt = x + 0.5 * (150.0 - pdfioContentTextMeasure(font, pdfio_labels[i], 18.0));
testBegin("pdfioContentTextMoveTo(%g, %g)", xt, y + 12.0);
if (pdfioContentTextMoveTo(st, xt, y + 12.0))
testEnd(true);
else
goto error;
testBegin("pdfioContentTextShow(\"%s\")", pdfio_labels[i]);
if (pdfioContentTextShow(st, false, pdfio_labels[i]))
{
testEnd(true);
}
else
{
testEnd(false);
goto error;
}
testBegin("pdfioContentTextEnd()");
if (pdfioContentTextEnd(st))
{
testEnd(true);
}
else
{
testEnd(false);
goto error;
}
snprintf(imgname, sizeof(imgname), "IM%u", (unsigned)(i + 11));
testBegin("pdfioContentDrawImage(\"%s\")", imgname);
if (pdfioContentDrawImage(st, imgname, x, y + 36, 150, 150))
{
testEnd(true);
}
else
{
testEnd(false);
goto error;
}
}
// Close the object and stream...
testBegin("pdfioStreamClose");
if (pdfioStreamClose(st))
{
testEnd(true);
}
else
{
testEnd(false);
return (1);
}
return (0);
error:
pdfioStreamClose(st);
return (1);
}
#endif // HAVE_LIBWEBP