diff options
-rw-r--r-- | core/fxcodec/codec/fx_codec_jpx_opj.cpp | 241 |
1 files changed, 122 insertions, 119 deletions
diff --git a/core/fxcodec/codec/fx_codec_jpx_opj.cpp b/core/fxcodec/codec/fx_codec_jpx_opj.cpp index 32c808fa8e..95e395b463 100644 --- a/core/fxcodec/codec/fx_codec_jpx_opj.cpp +++ b/core/fxcodec/codec/fx_codec_jpx_opj.cpp @@ -26,97 +26,23 @@ #include "third_party/lcms2-2.6/include/lcms2.h" #endif -static void fx_error_callback(const char* msg, void* client_data) { - (void)client_data; -} +namespace { -static void fx_warning_callback(const char* msg, void* client_data) { +void fx_error_callback(const char* msg, void* client_data) { (void)client_data; } -static void fx_info_callback(const char* msg, void* client_data) { +void fx_warning_callback(const char* msg, void* client_data) { (void)client_data; } -OPJ_SIZE_T opj_read_from_memory(void* p_buffer, - OPJ_SIZE_T nb_bytes, - void* p_user_data) { - DecodeData* srcData = static_cast<DecodeData*>(p_user_data); - if (!srcData || !srcData->src_data || srcData->src_size == 0) - return static_cast<OPJ_SIZE_T>(-1); - - // Reads at EOF return an error code. - if (srcData->offset >= srcData->src_size) - return static_cast<OPJ_SIZE_T>(-1); - - OPJ_SIZE_T bufferLength = srcData->src_size - srcData->offset; - OPJ_SIZE_T readlength = nb_bytes < bufferLength ? nb_bytes : bufferLength; - memcpy(p_buffer, &srcData->src_data[srcData->offset], readlength); - srcData->offset += readlength; - return readlength; -} - -OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data) { - DecodeData* srcData = static_cast<DecodeData*>(p_user_data); - if (!srcData || !srcData->src_data || srcData->src_size == 0) - return static_cast<OPJ_OFF_T>(-1); - - // Offsets are signed and may indicate a negative skip. Do not support this - // because of the strange return convention where either bytes skipped or - // -1 is returned. Following that convention, a successful relative seek of - // -1 bytes would be required to to give the same result as the error case. - if (nb_bytes < 0) - return static_cast<OPJ_OFF_T>(-1); - - // FIXME: use std::make_unsigned<OPJ_OFF_T>::type once c++11 lib is OK'd. - uint64_t unsignedNbBytes = static_cast<uint64_t>(nb_bytes); - // Additionally, the offset may take us beyond the range of a size_t (e.g. - // 32-bit platforms). If so, just clamp at EOF. - if (unsignedNbBytes > - std::numeric_limits<OPJ_SIZE_T>::max() - srcData->offset) { - srcData->offset = srcData->src_size; - } else { - OPJ_SIZE_T checkedNbBytes = static_cast<OPJ_SIZE_T>(unsignedNbBytes); - // Otherwise, mimic fseek() semantics to always succeed, even past EOF, - // clamping at EOF. We can get away with this since we don't actually - // provide negative relative skips from beyond EOF back to inside the - // data, which would be the only reason to need to know exactly how far - // beyond EOF we are. - srcData->offset = - std::min(srcData->offset + checkedNbBytes, srcData->src_size); - } - return nb_bytes; -} - -OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data) { - DecodeData* srcData = static_cast<DecodeData*>(p_user_data); - if (!srcData || !srcData->src_data || srcData->src_size == 0) - return OPJ_FALSE; - - // Offsets are signed and may indicate a negative position, which would - // be before the start of the file. Do not support this. - if (nb_bytes < 0) - return OPJ_FALSE; - - // FIXME: use std::make_unsigned<OPJ_OFF_T>::type once c++11 lib is OK'd. - uint64_t unsignedNbBytes = static_cast<uint64_t>(nb_bytes); - // Additionally, the offset may take us beyond the range of a size_t (e.g. - // 32-bit platforms). If so, just clamp at EOF. - if (unsignedNbBytes > std::numeric_limits<OPJ_SIZE_T>::max()) { - srcData->offset = srcData->src_size; - } else { - OPJ_SIZE_T checkedNbBytes = static_cast<OPJ_SIZE_T>(nb_bytes); - // Otherwise, mimic fseek() semantics to always succeed, even past EOF, - // again clamping at EOF. - srcData->offset = std::min(checkedNbBytes, srcData->src_size); - } - return OPJ_TRUE; +void fx_info_callback(const char* msg, void* client_data) { + (void)client_data; } -static opj_stream_t* fx_opj_stream_create_memory_stream( - DecodeData* data, - OPJ_SIZE_T p_size, - OPJ_BOOL p_is_read_stream) { +opj_stream_t* fx_opj_stream_create_memory_stream(DecodeData* data, + OPJ_SIZE_T p_size, + OPJ_BOOL p_is_read_stream) { if (!data || !data->src_data || data->src_size <= 0) return nullptr; @@ -132,14 +58,14 @@ static opj_stream_t* fx_opj_stream_create_memory_stream( return stream; } -static void sycc_to_rgb(int offset, - int upb, - int y, - int cb, - int cr, - int* out_r, - int* out_g, - int* out_b) { +void sycc_to_rgb(int offset, + int upb, + int y, + int cb, + int cr, + int* out_r, + int* out_g, + int* out_b) { int r, g, b; cb -= offset; cr -= offset; @@ -166,7 +92,7 @@ static void sycc_to_rgb(int offset, *out_b = b; } -static void sycc444_to_rgb(opj_image_t* img) { +void sycc444_to_rgb(opj_image_t* img) { int prec = img->comps[0].prec; // If we shift 31 we're going to go negative, then things go bad. if (prec > 30) @@ -211,24 +137,24 @@ static void sycc444_to_rgb(opj_image_t* img) { img->comps[2].data = d2; } -static bool sycc420_422_size_is_valid(opj_image_t* img) { +bool sycc420_422_size_is_valid(opj_image_t* img) { return (img && img->comps[0].w != std::numeric_limits<OPJ_UINT32>::max() && (img->comps[0].w + 1) / 2 == img->comps[1].w && img->comps[1].w == img->comps[2].w && img->comps[1].h == img->comps[2].h); } -static bool sycc420_size_is_valid(opj_image_t* img) { +bool sycc420_size_is_valid(opj_image_t* img) { return (sycc420_422_size_is_valid(img) && img->comps[0].h != std::numeric_limits<OPJ_UINT32>::max() && (img->comps[0].h + 1) / 2 == img->comps[1].h); } -static bool sycc422_size_is_valid(opj_image_t* img) { +bool sycc422_size_is_valid(opj_image_t* img) { return (sycc420_422_size_is_valid(img) && img->comps[0].h == img->comps[1].h); } -static void sycc422_to_rgb(opj_image_t* img) { +void sycc422_to_rgb(opj_image_t* img) { if (!sycc422_size_is_valid(img)) return; @@ -299,10 +225,110 @@ static void sycc422_to_rgb(opj_image_t* img) { img->comps[2].dy = img->comps[0].dy; } -static bool sycc420_must_extend_cbcr(OPJ_UINT32 y, OPJ_UINT32 cbcr) { +bool sycc420_must_extend_cbcr(OPJ_UINT32 y, OPJ_UINT32 cbcr) { return (y & 1) && (cbcr == y / 2); } +void color_sycc_to_rgb(opj_image_t* img) { + if (img->numcomps < 3) { + img->color_space = OPJ_CLRSPC_GRAY; + return; + } + if ((img->comps[0].dx == 1) && (img->comps[1].dx == 2) && + (img->comps[2].dx == 2) && (img->comps[0].dy == 1) && + (img->comps[1].dy == 2) && (img->comps[2].dy == 2)) { + sycc420_to_rgb(img); + } else if ((img->comps[0].dx == 1) && (img->comps[1].dx == 2) && + (img->comps[2].dx == 2) && (img->comps[0].dy == 1) && + (img->comps[1].dy == 1) && (img->comps[2].dy == 1)) { + sycc422_to_rgb(img); + } else if ((img->comps[0].dx == 1) && (img->comps[1].dx == 1) && + (img->comps[2].dx == 1) && (img->comps[0].dy == 1) && + (img->comps[1].dy == 1) && (img->comps[2].dy == 1)) { + sycc444_to_rgb(img); + } else { + return; + } + img->color_space = OPJ_CLRSPC_SRGB; +} + +} // namespace + +OPJ_SIZE_T opj_read_from_memory(void* p_buffer, + OPJ_SIZE_T nb_bytes, + void* p_user_data) { + DecodeData* srcData = static_cast<DecodeData*>(p_user_data); + if (!srcData || !srcData->src_data || srcData->src_size == 0) + return static_cast<OPJ_SIZE_T>(-1); + + // Reads at EOF return an error code. + if (srcData->offset >= srcData->src_size) + return static_cast<OPJ_SIZE_T>(-1); + + OPJ_SIZE_T bufferLength = srcData->src_size - srcData->offset; + OPJ_SIZE_T readlength = nb_bytes < bufferLength ? nb_bytes : bufferLength; + memcpy(p_buffer, &srcData->src_data[srcData->offset], readlength); + srcData->offset += readlength; + return readlength; +} + +OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data) { + DecodeData* srcData = static_cast<DecodeData*>(p_user_data); + if (!srcData || !srcData->src_data || srcData->src_size == 0) + return static_cast<OPJ_OFF_T>(-1); + + // Offsets are signed and may indicate a negative skip. Do not support this + // because of the strange return convention where either bytes skipped or + // -1 is returned. Following that convention, a successful relative seek of + // -1 bytes would be required to to give the same result as the error case. + if (nb_bytes < 0) + return static_cast<OPJ_OFF_T>(-1); + + // FIXME: use std::make_unsigned<OPJ_OFF_T>::type once c++11 lib is OK'd. + uint64_t unsignedNbBytes = static_cast<uint64_t>(nb_bytes); + // Additionally, the offset may take us beyond the range of a size_t (e.g. + // 32-bit platforms). If so, just clamp at EOF. + if (unsignedNbBytes > + std::numeric_limits<OPJ_SIZE_T>::max() - srcData->offset) { + srcData->offset = srcData->src_size; + } else { + OPJ_SIZE_T checkedNbBytes = static_cast<OPJ_SIZE_T>(unsignedNbBytes); + // Otherwise, mimic fseek() semantics to always succeed, even past EOF, + // clamping at EOF. We can get away with this since we don't actually + // provide negative relative skips from beyond EOF back to inside the + // data, which would be the only reason to need to know exactly how far + // beyond EOF we are. + srcData->offset = + std::min(srcData->offset + checkedNbBytes, srcData->src_size); + } + return nb_bytes; +} + +OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data) { + DecodeData* srcData = static_cast<DecodeData*>(p_user_data); + if (!srcData || !srcData->src_data || srcData->src_size == 0) + return OPJ_FALSE; + + // Offsets are signed and may indicate a negative position, which would + // be before the start of the file. Do not support this. + if (nb_bytes < 0) + return OPJ_FALSE; + + // FIXME: use std::make_unsigned<OPJ_OFF_T>::type once c++11 lib is OK'd. + uint64_t unsignedNbBytes = static_cast<uint64_t>(nb_bytes); + // Additionally, the offset may take us beyond the range of a size_t (e.g. + // 32-bit platforms). If so, just clamp at EOF. + if (unsignedNbBytes > std::numeric_limits<OPJ_SIZE_T>::max()) { + srcData->offset = srcData->src_size; + } else { + OPJ_SIZE_T checkedNbBytes = static_cast<OPJ_SIZE_T>(nb_bytes); + // Otherwise, mimic fseek() semantics to always succeed, even past EOF, + // again clamping at EOF. + srcData->offset = std::min(checkedNbBytes, srcData->src_size); + } + return OPJ_TRUE; +} + void sycc420_to_rgb(opj_image_t* img) { if (!sycc420_size_is_valid(img)) return; @@ -443,29 +469,6 @@ void sycc420_to_rgb(opj_image_t* img) { img->comps[2].dy = img->comps[0].dy; } -static void color_sycc_to_rgb(opj_image_t* img) { - if (img->numcomps < 3) { - img->color_space = OPJ_CLRSPC_GRAY; - return; - } - if ((img->comps[0].dx == 1) && (img->comps[1].dx == 2) && - (img->comps[2].dx == 2) && (img->comps[0].dy == 1) && - (img->comps[1].dy == 2) && (img->comps[2].dy == 2)) { - sycc420_to_rgb(img); - } else if ((img->comps[0].dx == 1) && (img->comps[1].dx == 2) && - (img->comps[2].dx == 2) && (img->comps[0].dy == 1) && - (img->comps[1].dy == 1) && (img->comps[2].dy == 1)) { - sycc422_to_rgb(img); - } else if ((img->comps[0].dx == 1) && (img->comps[1].dx == 1) && - (img->comps[2].dx == 1) && (img->comps[0].dy == 1) && - (img->comps[1].dy == 1) && (img->comps[2].dy == 1)) { - sycc444_to_rgb(img); - } else { - return; - } - img->color_space = OPJ_CLRSPC_SRGB; -} - CJPX_Decoder::CJPX_Decoder(CPDF_ColorSpace* cs) : image(nullptr), l_codec(nullptr), l_stream(nullptr), m_ColorSpace(cs) {} |