From 9cc0f439ac4208eabda07bf5e0afc9de89b3d71a Mon Sep 17 00:00:00 2001
From: Aaron Bishop <aaron@cfssolutions.com>
Date: Thu, 5 Oct 2017 15:16:10 -0400
Subject: [PATCH] Implement HPDF_Image_LoadCcittImageFromMemory, allowing for
quickly adding CCITT data without decoding and reencoding first.
Example use:
HPDF_BYTE *buffer = NULL;
TIFF* tif = TIFFOpen(file, "r");
HPDF_UINT32 tw, th, *sbc, strips;
HPDF_UINT16 pm, bps, comp;
size_t c = 0, o = 0;
tmsize_t tr;
HPDF_Image image;
TIFFGetFieldDefaulted(tif, TIFFTAG_IMAGEWIDTH, &tw, 0);
TIFFGetFieldDefaulted(tif, TIFFTAG_IMAGELENGTH, &th, 0);
TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps, 0);
TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &pm, PHOTOMETRIC_MINISWHITE);
TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &comp, COMPRESSION_CCITTFAX4);
TIFFGetFieldDefaulted(tif, TIFFTAG_STRIPBYTECOUNTS, &sbc, NULL);
if(bp2 == 1 && (pm == PHOTOMETRIC_MINISBLACK || pm == PHOTOMETRIC_MINISWHITE) && comp == COMPRESSION_CCITTFAX4 && sbc != NULL) {
strips = TIFFNumberOfStrips(tif);
for(HPDF_UINT32* itr = sbc, end = sbc + strips; itr != end; ++itr)
c += *itr;
buffer = malloc(sizeof(HPDF_BYTE) * c);
for(tstrip_t i = o; i < strips; ++i) {
if((tr = TIFFReadRawStrip(tif, i, &buffer[0], sbc[i])) != sbc[i]) {
free(buffer);
return NULL;
}
o += sbc[i];
}
image = HPDF_Image_LoadCcittImageFromMemory(mmgr, xref, buffer, c, tw, th, pm != PHOTOMETRIC_MINISWHITE);
free(buffer);
return image;
}
...
---
include/hpdf_image.h | 9 ++++++++
src/hpdf_image.c | 52 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/include/hpdf_image.h b/include/hpdf_image.h
index 4e1aa6c..7d1ce4d 100644
--- a/include/hpdf_image.h
+++ b/include/hpdf_image.h
@@ -34,6 +34,15 @@ HPDF_Image_Load1BitImageFromMem (HPDF_MMgr mmgr,
HPDF_BOOL top_is_first
);
+HPDF_Image
+HPDF_Image_LoadCcittImageFromMemory (HPDF_MMgr mmgr,
+ HPDF_Xref xref,
+ const HPDF_BYTE* buffer,
+ const HPDF_UINT buffer_size,
+ const HPDF_INT32 width,
+ const HPDF_INT32 height,
+ HPDF_BOOL black_is1
+ );
#ifndef LIBHPDF_HAVE_NOPNGLIB
diff --git a/src/hpdf_image.c b/src/hpdf_image.c
index eeec7c2..d370c9a 100644
--- a/src/hpdf_image.c
+++ b/src/hpdf_image.c
@@ -393,6 +393,58 @@ HPDF_Image_LoadRawImageFromMem (HPDF_MMgr mmgr,
return image;
}
+HPDF_Image
+HPDF_Image_LoadCcittImageFromMemory (HPDF_MMgr mmgr, HPDF_Xref xref, const HPDF_BYTE* buffer, const HPDF_UINT buffer_size, const HPDF_INT32 width, const HPDF_INT32 height, HPDF_BOOL black_is1)
+{
+ HPDF_Dict image;
+ HPDF_STATUS ret = HPDF_OK;
+ /* HPDF_UINT size; */
+
+ HPDF_PTRACE ((" HPDF_Image_LoadCcittImageFromMemory\n"));
+
+ image = HPDF_DictStream_New (mmgr, xref);
+ if (!image)
+ return NULL;
+
+ image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
+ ret += HPDF_Dict_AddName (image, "Type", "XObject");
+ ret += HPDF_Dict_AddName (image, "Subtype", "Image");
+ if (ret != HPDF_OK)
+ return NULL;
+
+ /* size = width * height; */
+ ret = HPDF_Dict_AddName (image, "ColorSpace", "DeviceGray");
+ if (ret != HPDF_OK)
+ return NULL;
+
+ if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK)
+ return NULL;
+
+ if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK)
+ return NULL;
+
+ if (HPDF_Dict_AddNumber (image, "BitsPerComponent", 1) != HPDF_OK)
+ return NULL;
+
+ if (HPDF_Stream_Write(image->stream, buffer, buffer_size) != HPDF_OK)
+ return NULL;
+
+ image->filter = HPDF_STREAM_FILTER_CCITT_DECODE;
+ image->filterParams = HPDF_Dict_New(mmgr);
+ if(image->filterParams == NULL)
+ return NULL;
+
+ /* pure 2D encoding, default is 0 */
+ HPDF_Dict_AddNumber (image->filterParams, "K", -1);
+ /* default is 1728 */
+ HPDF_Dict_AddNumber (image->filterParams, "Columns", width);
+ /* default is 0 */
+ HPDF_Dict_AddNumber (image->filterParams, "Rows", height);
+ HPDF_Dict_AddBoolean (image->filterParams, "BlackIs1", black_is1);
+
+ return image;
+}
+
HPDF_BOOL
HPDF_Image_Validate (HPDF_Image image)
--
2.21.1 (Apple Git-122.3)