static HPDF_STATUS Get3DStreamType (HPDF_Stream stream, const char **type) { HPDF_BYTE tag[4]; HPDF_UINT len; HPDF_PTRACE ((" HPDF_U3D_Get3DStreamType\n")); len = 4; if (HPDF_Stream_Read (stream, tag, &len) != HPDF_OK) { return HPDF_Error_GetCode (stream->error); } if (HPDF_Stream_Seek (stream, 0, HPDF_SEEK_SET) != HPDF_OK) { return HPDF_Error_GetCode (stream->error); } if (HPDF_MemCmp(tag, (HPDF_BYTE *)u3d, 4/* yes, \0 is required */) == 0) { *type = u3d; return HPDF_OK; } if (HPDF_MemCmp(tag, (HPDF_BYTE *)prc, 3) == 0) { *type = prc; return HPDF_OK; } return HPDF_INVALID_U3D_DATA; }
HPDF_ReadFromStream (HPDF_Doc pdf, HPDF_BYTE *buf, HPDF_UINT32 *size) { HPDF_UINT isize = *size; HPDF_STATUS ret; if (!HPDF_HasDoc (pdf)) return HPDF_INVALID_DOCUMENT; if (!HPDF_Stream_Validate (pdf->stream)) return HPDF_RaiseError (&pdf->error, HPDF_INVALID_OPERATION, 0); if (*size == 0) return HPDF_RaiseError (&pdf->error, HPDF_INVALID_PARAMETER, 0); ret = HPDF_Stream_Read (pdf->stream, buf, &isize); *size = isize; if (ret != HPDF_OK) HPDF_CheckError (&pdf->error); return ret; }
HPDF_GetContents (HPDF_Doc pdf, HPDF_BYTE *buf, HPDF_UINT32 *size) { HPDF_Stream stream; HPDF_UINT isize; HPDF_STATUS ret; HPDF_PTRACE ((" HPDF_GetContents\n")); if (!HPDF_HasDoc (pdf)) { return HPDF_INVALID_DOCUMENT; } stream = HPDF_MemStream_New (pdf->mmgr, HPDF_STREAM_BUF_SIZ); if (!stream) { return HPDF_CheckError (&pdf->error); } if (InternalSaveToStream (pdf, stream) != HPDF_OK) { HPDF_Stream_Free (stream); return HPDF_CheckError (&pdf->error); } ret = HPDF_Stream_Read (stream, buf, &isize); *size = isize; HPDF_Stream_Free (stream); return ret; }
static void PngReadFunc (png_structp png_ptr, png_bytep data, png_uint_32 length) { HPDF_UINT len = length; HPDF_Stream stream = (HPDF_Stream)png_get_io_ptr (png_ptr); HPDF_Stream_Read (stream, data, &len); }
HPDF_Image HPDF_Image_LoadJpegImage (HPDF_MMgr mmgr, HPDF_Stream jpeg_data, HPDF_Xref xref) { HPDF_Dict image; HPDF_STATUS ret = HPDF_OK; HPDF_PTRACE ((" HPDF_Image_LoadJpegImage\n")); image = HPDF_DictStream_New (mmgr, xref); if (!image) return NULL; image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT; /* add requiered elements */ image->filter = HPDF_STREAM_FILTER_DCT_DECODE; ret += HPDF_Dict_AddName (image, "Type", "XObject"); ret += HPDF_Dict_AddName (image, "Subtype", "Image"); if (ret != HPDF_OK) return NULL; if (LoadJpegHeader (image, jpeg_data) != HPDF_OK) return NULL; if (HPDF_Stream_Seek (jpeg_data, 0, HPDF_SEEK_SET) != HPDF_OK) return NULL; for (;;) { HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ]; HPDF_UINT len = HPDF_STREAM_BUF_SIZ; HPDF_STATUS ret = HPDF_Stream_Read (jpeg_data, buf, &len); if (ret != HPDF_OK) { if (ret == HPDF_STREAM_EOF) { if (len > 0) { ret = HPDF_Stream_Write (image->stream, buf, len); if (ret != HPDF_OK) return NULL; } break; } else return NULL; } if (HPDF_Stream_Write (image->stream, buf, len) != HPDF_OK) return NULL; } return image; }
static HPDF_STATUS PngBeforeWrite (HPDF_Dict obj) { HPDF_STATUS ret; png_byte header[HPDF_PNG_BYTES_TO_CHECK]; HPDF_UINT len = HPDF_PNG_BYTES_TO_CHECK; HPDF_Stream png_data; HPDF_String s; HPDF_PTRACE ((" PngBeforeWrite\n")); HPDF_MemStream_FreeData(obj->stream); s = HPDF_Dict_GetItem (obj, "_FILE_NAME", HPDF_OCLASS_STRING); if (!s) return HPDF_SetError (obj->error, HPDF_MISSING_FILE_NAME_ENTRY, 0); png_data = HPDF_FileReader_New (obj->mmgr, (const char *)(s->value)); if (!HPDF_Stream_Validate (png_data)) return obj->error->error_no; HPDF_MemSet (header, 0x00, HPDF_PNG_BYTES_TO_CHECK); ret = HPDF_Stream_Read (png_data, header, &len); if (ret != HPDF_OK || png_sig_cmp (header, (png_size_t)0, HPDF_PNG_BYTES_TO_CHECK)) { HPDF_Stream_Free(png_data); return HPDF_SetError (obj->error, HPDF_INVALID_PNG_IMAGE, 0); } if ((ret = LoadPngData (obj, NULL, png_data, HPDF_FALSE)) != HPDF_OK) { HPDF_Stream_Free(png_data); return ret; } HPDF_Stream_Free(png_data); return HPDF_OK; }
HPDF_Image HPDF_Image_LoadPngImage (HPDF_MMgr mmgr, HPDF_Stream png_data, HPDF_Xref xref, HPDF_BOOL delayed_loading) { HPDF_STATUS ret; HPDF_Dict image; png_byte header[HPDF_PNG_BYTES_TO_CHECK]; HPDF_UINT len = HPDF_PNG_BYTES_TO_CHECK; HPDF_PTRACE ((" HPDF_Image_LoadPngImage\n")); HPDF_MemSet (header, 0x00, HPDF_PNG_BYTES_TO_CHECK); ret = HPDF_Stream_Read (png_data, header, &len); if (ret != HPDF_OK || png_sig_cmp (header, (png_size_t)0, HPDF_PNG_BYTES_TO_CHECK)) { HPDF_SetError (mmgr->error, HPDF_INVALID_PNG_IMAGE, 0); return NULL; } 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; if (LoadPngData (image, xref, png_data, delayed_loading) != HPDF_OK) return NULL; return image; }
HPDF_U3D HPDF_U3D_LoadU3D (HPDF_MMgr mmgr, HPDF_Stream u3d_data, HPDF_Xref xref) { HPDF_Dict u3d; const char *type; HPDF_PTRACE ((" HPDF_U3D_LoadU3D\n")); u3d = HPDF_DictStream_New (mmgr, xref); if (!u3d) { return NULL; } u3d->header.obj_class |= HPDF_OSUBCLASS_XOBJECT; /* add required elements */ u3d->filter = HPDF_STREAM_FILTER_NONE; if (HPDF_Dict_AddName (u3d, "Type", "3D") != HPDF_OK) { HPDF_Dict_Free(u3d); return NULL; } if (Get3DStreamType (u3d_data, &type) != HPDF_OK) { HPDF_Dict_Free(u3d); return NULL; } if (HPDF_Dict_AddName (u3d, "Subtype", type) != HPDF_OK) { HPDF_Dict_Free(u3d); return NULL; } for (;;) { HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ]; HPDF_UINT len = HPDF_STREAM_BUF_SIZ; HPDF_STATUS ret = HPDF_Stream_Read (u3d_data, buf, &len); if (ret != HPDF_OK) { if (ret == HPDF_STREAM_EOF) { if (len > 0) { ret = HPDF_Stream_Write (u3d->stream, buf, len); if (ret != HPDF_OK) { HPDF_Dict_Free(u3d); return NULL; } } break; } else { HPDF_Dict_Free(u3d); return NULL; } } if (HPDF_Stream_Write (u3d->stream, buf, len) != HPDF_OK) { HPDF_Dict_Free(u3d); return NULL; } } return u3d; }
static HPDF_STATUS LoadJpegHeader (HPDF_Image image, HPDF_Stream stream) { HPDF_UINT16 tag; HPDF_UINT16 height; HPDF_UINT16 width; HPDF_BYTE precision; HPDF_BYTE num_components; const char *color_space_name; HPDF_UINT len; HPDF_STATUS ret; HPDF_Array array; HPDF_PTRACE ((" HPDF_Image_LoadJpegHeader\n")); len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&tag, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&tag); if (tag != 0xFFD8) return HPDF_INVALID_JPEG_DATA; /* find SOF record */ for (;;) { HPDF_UINT16 size; len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&tag, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&tag); len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&size, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&size); HPDF_PTRACE (("tag=%04X size=%u\n", tag, size)); if (tag == 0xFFC0 || tag == 0xFFC1 || tag == 0xFFC2 || tag == 0xFFC9) { len = 1; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&precision, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&height, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&height); len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&width, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&width); len = 1; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&num_components, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); break; } else if ((tag | 0x00FF) != 0xFFFF) /* lost marker */ return HPDF_SetError (image->error, HPDF_UNSUPPORTED_JPEG_FORMAT, 0); if (HPDF_Stream_Seek (stream, size - 2, HPDF_SEEK_CUR) != HPDF_OK) return HPDF_Error_GetCode (stream->error); } if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK) return HPDF_Error_GetCode (stream->error); if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK) return HPDF_Error_GetCode (stream->error); /* classification of RGB and CMYK is less than perfect * YCbCr and YCCK are classified into RGB or CMYK. * * It is necessary to read APP14 data to distinguish colorspace perfectly. */ switch (num_components) { case 1: color_space_name = COL_GRAY; break; case 3: color_space_name = COL_RGB; break; case 4: array = HPDF_Array_New (image->mmgr); if (!array) return HPDF_Error_GetCode (stream->error); ret = HPDF_Dict_Add (image, "Decode", array); if (ret != HPDF_OK) return HPDF_Error_GetCode (stream->error); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0)); if (ret != HPDF_OK) return HPDF_Error_GetCode (stream->error); color_space_name = COL_CMYK; break; default: return HPDF_SetError (image->error, HPDF_UNSUPPORTED_JPEG_FORMAT, 0); } if (HPDF_Dict_Add (image, "ColorSpace", HPDF_Name_New (image->mmgr, color_space_name)) != HPDF_OK) return HPDF_Error_GetCode (stream->error); if (HPDF_Dict_Add (image, "BitsPerComponent", HPDF_Number_New (image->mmgr, precision)) != HPDF_OK) return HPDF_Error_GetCode (stream->error); return HPDF_OK; }
static HPDF_STATUS LoadFontData (HPDF_FontDef fontdef, HPDF_Stream stream) { HPDF_Type1FontDefAttr attr = (HPDF_Type1FontDefAttr)fontdef->attr; char buf[HPDF_STREAM_BUF_SIZ]; char* pbuf = buf; HPDF_UINT len = 0; HPDF_STATUS ret; HPDF_BOOL end_flg = HPDF_FALSE; HPDF_PTRACE (" LoadFontData\n"); attr->font_data = HPDF_MemStream_New (fontdef->mmgr, HPDF_STREAM_BUF_SIZ); if (!attr->font_data) return HPDF_Error_GetCode (fontdef->error); len = 11; ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)pbuf, &len); if (ret != HPDF_OK) return ret; pbuf += 11; for (;;) { len = HPDF_STREAM_BUF_SIZ - 11; ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)pbuf, &len); if (ret == HPDF_STREAM_EOF) { end_flg = HPDF_TRUE; } else if (ret != HPDF_OK) return ret; if (len > 0) { if (attr->length1 == 0) { const char *s1 = HPDF_StrStr (buf, "eexec", len + 11); /* length1 indicate the size of ascii-data of font-file. */ if (s1) attr->length1 = attr->font_data->size + (s1 - buf) + 6; } if (attr->length1 > 0 && attr->length2 == 0) { const char *s2 = HPDF_StrStr (buf, "cleartomark", len + 11); if (s2) attr->length2 = attr->font_data->size + - 520 - attr->length1 + (s2 - buf); /* length1 indicate the size of binary-data. * in most fonts, it is all right at 520 bytes . but it need * to modify because it does not fully satisfy the * specification of type-1 font. */ } } if (end_flg) { if ((ret = HPDF_Stream_Write (attr->font_data, (HPDF_BYTE *)buf, len + 11)) != HPDF_OK) return ret; break; } else { if ((ret = HPDF_Stream_Write (attr->font_data, (HPDF_BYTE *)buf, len)) != HPDF_OK) return ret; HPDF_MemCpy ((HPDF_BYTE *)buf, (HPDF_BYTE *)buf + len, 11); pbuf = buf + 11; } } if (attr->length1 == 0 || attr->length2 == 0) return HPDF_SetError (fontdef->error, HPDF_UNSUPPORTED_TYPE1_FONT, 0); attr->length3 = attr->font_data->size - attr->length1 - attr->length2; return HPDF_OK; }