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)

