diff options
Diffstat (limited to 'lib/extras/codec.cc')
-rw-r--r-- | lib/extras/codec.cc | 114 |
1 files changed, 49 insertions, 65 deletions
diff --git a/lib/extras/codec.cc b/lib/extras/codec.cc index 774b4cc..3ba31f2 100644 --- a/lib/extras/codec.cc +++ b/lib/extras/codec.cc @@ -5,27 +5,18 @@ #include "lib/extras/codec.h" -#include "jxl/decode.h" -#include "jxl/types.h" -#include "lib/extras/packed_image.h" -#include "lib/jxl/base/padded_bytes.h" -#include "lib/jxl/base/status.h" +#include <jxl/decode.h> +#include <jxl/types.h> -#if JPEGXL_ENABLE_APNG +#include "lib/extras/dec/decode.h" #include "lib/extras/enc/apng.h" -#endif -#if JPEGXL_ENABLE_JPEG -#include "lib/extras/enc/jpg.h" -#endif -#if JPEGXL_ENABLE_EXR #include "lib/extras/enc/exr.h" -#endif - -#include "lib/extras/dec/decode.h" +#include "lib/extras/enc/jpg.h" #include "lib/extras/enc/pgx.h" #include "lib/extras/enc/pnm.h" +#include "lib/extras/packed_image.h" #include "lib/extras/packed_image_convert.h" -#include "lib/jxl/base/file_io.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/image_bundle.h" namespace jxl { @@ -38,30 +29,21 @@ constexpr size_t kMinBytes = 9; Status SetFromBytes(const Span<const uint8_t> bytes, const extras::ColorHints& color_hints, CodecInOut* io, - ThreadPool* pool, extras::Codec* orig_codec) { + ThreadPool* pool, const SizeConstraints* constraints, + extras::Codec* orig_codec) { if (bytes.size() < kMinBytes) return JXL_FAILURE("Too few bytes"); extras::PackedPixelFile ppf; - if (extras::DecodeBytes(bytes, color_hints, io->constraints, &ppf, - orig_codec)) { + if (extras::DecodeBytes(bytes, color_hints, &ppf, constraints, orig_codec)) { return ConvertPackedPixelFileToCodecInOut(ppf, pool, io); } return JXL_FAILURE("Codecs failed to decode"); } -Status SetFromFile(const std::string& pathname, - const extras::ColorHints& color_hints, CodecInOut* io, - ThreadPool* pool, extras::Codec* orig_codec) { - std::vector<uint8_t> encoded; - JXL_RETURN_IF_ERROR(ReadFile(pathname, &encoded)); - JXL_RETURN_IF_ERROR(SetFromBytes(Span<const uint8_t>(encoded), color_hints, - io, pool, orig_codec)); - return true; -} - Status Encode(const CodecInOut& io, const extras::Codec codec, const ColorEncoding& c_desired, size_t bits_per_sample, std::vector<uint8_t>* bytes, ThreadPool* pool) { + bytes->clear(); JXL_CHECK(!io.Main().c_current().ICC().empty()); JXL_CHECK(!c_desired.ICC().empty()); io.CheckMetadata(); @@ -77,22 +59,22 @@ Status Encode(const CodecInOut& io, const extras::Codec codec, std::ostringstream os; switch (codec) { case extras::Codec::kPNG: -#if JPEGXL_ENABLE_APNG encoder = extras::GetAPNGEncoder(); - break; -#else - return JXL_FAILURE("JPEG XL was built without (A)PNG support"); -#endif + if (encoder) { + break; + } else { + return JXL_FAILURE("JPEG XL was built without (A)PNG support"); + } case extras::Codec::kJPG: -#if JPEGXL_ENABLE_JPEG format.data_type = JXL_TYPE_UINT8; encoder = extras::GetJPEGEncoder(); - os << io.jpeg_quality; - encoder->SetOption("q", os.str()); - break; -#else - return JXL_FAILURE("JPEG XL was built without JPEG support"); -#endif + if (encoder) { + os << io.jpeg_quality; + encoder->SetOption("q", os.str()); + break; + } else { + return JXL_FAILURE("JPEG XL was built without JPEG support"); + } case extras::Codec::kPNM: if (io.Main().HasAlpha()) { encoder = extras::GetPAMEncoder(); @@ -102,14 +84,9 @@ Status Encode(const CodecInOut& io, const extras::Codec codec, encoder = extras::GetPPMEncoder(); } else { format.data_type = JXL_TYPE_FLOAT; - format.endianness = JXL_NATIVE_ENDIAN; + format.endianness = JXL_LITTLE_ENDIAN; encoder = extras::GetPFMEncoder(); } - if (!c_desired.IsSRGB()) { - JXL_WARNING( - "PNM encoder cannot store custom ICC profile; decoder " - "will need hint key=color_space to get the same values"); - } break; case extras::Codec::kPGX: encoder = extras::GetPGXEncoder(); @@ -117,13 +94,17 @@ Status Encode(const CodecInOut& io, const extras::Codec codec, case extras::Codec::kGIF: return JXL_FAILURE("Encoding to GIF is not implemented"); case extras::Codec::kEXR: -#if JPEGXL_ENABLE_EXR format.data_type = JXL_TYPE_FLOAT; encoder = extras::GetEXREncoder(); - break; -#else - return JXL_FAILURE("JPEG XL was built without OpenEXR support"); -#endif + if (encoder) { + break; + } else { + return JXL_FAILURE("JPEG XL was built without OpenEXR support"); + } + case extras::Codec::kJXL: + // TODO(user): implement + return JXL_FAILURE("Codec::kJXL is not supported yet"); + case extras::Codec::kUnknown: return JXL_FAILURE("Cannot encode using Codec::kUnknown"); } @@ -135,6 +116,11 @@ Status Encode(const CodecInOut& io, const extras::Codec codec, extras::PackedPixelFile ppf; JXL_RETURN_IF_ERROR( ConvertCodecInOutToPackedPixelFile(io, format, c_desired, pool, &ppf)); + ppf.info.bits_per_sample = bits_per_sample; + if (format.data_type == JXL_TYPE_FLOAT) { + ppf.info.bits_per_sample = 32; + ppf.info.exponent_bits_per_sample = 8; + } extras::EncodedImage encoded_image; JXL_RETURN_IF_ERROR(encoder->Encode(ppf, &encoded_image, pool)); JXL_ASSERT(encoded_image.bitstreams.size() == 1); @@ -143,15 +129,15 @@ Status Encode(const CodecInOut& io, const extras::Codec codec, return true; } -Status EncodeToFile(const CodecInOut& io, const ColorEncoding& c_desired, - size_t bits_per_sample, const std::string& pathname, - ThreadPool* pool) { - const std::string extension = Extension(pathname); - const extras::Codec codec = - extras::CodecFromExtension(extension, &bits_per_sample); +Status Encode(const CodecInOut& io, const ColorEncoding& c_desired, + size_t bits_per_sample, const std::string& pathname, + std::vector<uint8_t>* bytes, ThreadPool* pool) { + std::string extension; + const extras::Codec codec = extras::CodecFromPath( + pathname, &bits_per_sample, /* filename */ nullptr, &extension); // Warn about incorrect usage of PGM/PGX/PPM - only the latter supports - // color, but CodecFromExtension lumps them all together. + // color, but CodecFromPath lumps them all together. if (codec == extras::Codec::kPNM && extension != ".pfm") { if (io.Main().HasAlpha() && extension != ".pam") { JXL_WARNING( @@ -174,16 +160,14 @@ Status EncodeToFile(const CodecInOut& io, const ColorEncoding& c_desired, bits_per_sample = 16; } - std::vector<uint8_t> encoded; - return Encode(io, codec, c_desired, bits_per_sample, &encoded, pool) && - WriteFile(encoded, pathname); + return Encode(io, codec, c_desired, bits_per_sample, bytes, pool); } -Status EncodeToFile(const CodecInOut& io, const std::string& pathname, - ThreadPool* pool) { +Status Encode(const CodecInOut& io, const std::string& pathname, + std::vector<uint8_t>* bytes, ThreadPool* pool) { // TODO(lode): need to take the floating_point_sample field into account - return EncodeToFile(io, io.metadata.m.color_encoding, - io.metadata.m.bit_depth.bits_per_sample, pathname, pool); + return Encode(io, io.metadata.m.color_encoding, + io.metadata.m.bit_depth.bits_per_sample, pathname, bytes, pool); } } // namespace jxl |