/*! * \brief readHeaderJpeg() * * \param[in] filename * \param[out] pw [optional] * [out] ph ([optional] * [out] pspp ([optional] samples/pixel * \param[out] pycck [optional] 1 if ycck color space; 0 otherwise * \param[out] pcmyk [optional] 1 if cmyk color space; 0 otherwise * \return 0 if OK, 1 on error */ l_int32 readHeaderJpeg(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pspp, l_int32 *pycck, l_int32 *pcmyk) { l_int32 ret; FILE *fp; PROCNAME("readHeaderJpeg"); if (pw) *pw = 0; if (ph) *ph = 0; if (pspp) *pspp = 0; if (pycck) *pycck = 0; if (pcmyk) *pcmyk = 0; if (!filename) return ERROR_INT("filename not defined", procName, 1); if (!pw && !ph && !pspp && !pycck && !pcmyk) return ERROR_INT("no results requested", procName, 1); if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", procName, 1); ret = freadHeaderJpeg(fp, pw, ph, pspp, pycck, pcmyk); fclose(fp); return ret; }
/*! * \brief readHeaderMemJpeg() * * \param[in] data const; jpeg-encoded * \param[in] size of data * \param[out] pw [optional] * [out] ph ([optional] * [out] pspp ([optional] samples/pixel * \param[out] pycck [optional] 1 if ycck color space; 0 otherwise * \param[out] pcmyk [optional] 1 if cmyk color space; 0 otherwise * \return 0 if OK, 1 on error */ l_int32 readHeaderMemJpeg(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pspp, l_int32 *pycck, l_int32 *pcmyk) { l_int32 ret; FILE *fp; PROCNAME("readHeaderMemJpeg"); if (pw) *pw = 0; if (ph) *ph = 0; if (pspp) *pspp = 0; if (pycck) *pycck = 0; if (pcmyk) *pcmyk = 0; if (!data) return ERROR_INT("data not defined", procName, 1); if (!pw && !ph && !pspp && !pycck && !pcmyk) return ERROR_INT("no results requested", procName, 1); if ((fp = fopenReadFromMemory(data, size)) == NULL) return ERROR_INT("stream not opened", procName, 1); ret = freadHeaderJpeg(fp, pw, ph, pspp, pycck, pcmyk); fclose(fp); return ret; }
/*! * readHeaderMemJpeg() * * Input: data (const; jpeg-encoded) * size (of data) * &w (<optional return>) * &h (<optional return>) * &spp (<optional return>, samples/pixel) * &ycck (<optional return>, 1 if ycck color space; 0 otherwise) * &cmyk (<optional return>, 1 if cmyk color space; 0 otherwise) * Return: 0 if OK, 1 on error */ l_int32 readHeaderMemJpeg(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pspp, l_int32 *pycck, l_int32 *pcmyk) { l_int32 ret; FILE *fp; PROCNAME("readHeaderMemJpeg"); if (pw) *pw = 0; if (ph) *ph = 0; if (pspp) *pspp = 0; if (pycck) *pycck = 0; if (pcmyk) *pcmyk = 0; if (!data) return ERROR_INT("data not defined", procName, 1); if (!pw && !ph && !pspp && !pycck && !pcmyk) return ERROR_INT("no results requested", procName, 1); #if HAVE_FMEMOPEN if ((fp = fmemopen((l_uint8 *)data, size, "r")) == NULL) return ERROR_INT("stream not opened", procName, 1); #else L_WARNING("work-around: writing to a temp file\n", procName); if ((fp = tmpfile()) == NULL) return ERROR_INT("tmpfile stream not opened", procName, 1); fwrite(data, 1, size, fp); rewind(fp); #endif /* HAVE_FMEMOPEN */ ret = freadHeaderJpeg(fp, pw, ph, pspp, pycck, pcmyk); fclose(fp); return ret; }
// TODO(jbreiden) I hear that you can pull the flate stream out // of a PNG file and, by mentioning the predictor in the PDF object, // make most of them work without transcoding. If so that's a big win // versus what we do now. Try it out. bool TessPDFRenderer::fileToPDFObj(char *filename, long int objnum, char **pdf_object, long int *pdf_object_size) { char b1[kBasicBufSize]; char b2[kBasicBufSize]; if (!pdf_object_size || !pdf_object) return false; *pdf_object = NULL; *pdf_object_size = 0; if (!filename) return false; FILE *fp = fopen(filename, "rb"); if (!fp) return false; int format; findFileFormatStream(fp, &format); if (format != IFF_JFIF_JPEG) { fclose(fp); return false; } fseek(fp, 0, SEEK_END); long int jpeg_size = ftell(fp); fseek(fp, 0, SEEK_SET); int spp, cmyk, w, h; freadHeaderJpeg(fp, &w, &h, &spp, NULL, &cmyk); const char *colorspace; switch (spp) { case 1: colorspace = "/DeviceGray"; break; case 3: colorspace = "/DeviceRGB"; break; case 4: if (cmyk) colorspace = "/DeviceCMYK"; else return false; break; default: return false; } // IMAGE snprintf(b1, sizeof(b1), "%ld 0 obj\n" "<<\n" " /Length %ld\n" " /Subtype /Image\n" " /ColorSpace %s\n" " /Width %d\n" " /Height %d\n" " /BitsPerComponent 8\n" " /Filter /DCTDecode\n" ">>\n" "stream\n", objnum, jpeg_size, colorspace, w, h); size_t b1_len = strlen(b1); snprintf(b2, sizeof(b2), "\n" "endstream\n" "endobj\n"); size_t b2_len = strlen(b2); *pdf_object_size = b1_len + jpeg_size + b2_len; *pdf_object = new char[*pdf_object_size]; if (!pdf_object) return false; memcpy(*pdf_object, b1, b1_len); if (static_cast<int>(fread(*pdf_object + b1_len, 1, jpeg_size, fp)) != jpeg_size) { delete[] pdf_object; return false; } memcpy(*pdf_object + b1_len + jpeg_size, b2, b2_len); fclose(fp); return true; }