libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

codec.cc (3522B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #include "lib/extras/codec.h"
      7 
      8 #include <jxl/decode.h>
      9 #include <jxl/types.h>
     10 
     11 #include "lib/extras/dec/decode.h"
     12 #include "lib/extras/enc/apng.h"
     13 #include "lib/extras/enc/exr.h"
     14 #include "lib/extras/enc/jpg.h"
     15 #include "lib/extras/enc/pgx.h"
     16 #include "lib/extras/enc/pnm.h"
     17 #include "lib/extras/packed_image.h"
     18 #include "lib/extras/packed_image_convert.h"
     19 #include "lib/jxl/base/status.h"
     20 #include "lib/jxl/image_bundle.h"
     21 
     22 namespace jxl {
     23 namespace {
     24 
     25 // Any valid encoding is larger (ensures codecs can read the first few bytes)
     26 constexpr size_t kMinBytes = 9;
     27 
     28 }  // namespace
     29 
     30 Status SetFromBytes(const Span<const uint8_t> bytes,
     31                     const extras::ColorHints& color_hints, CodecInOut* io,
     32                     ThreadPool* pool, const SizeConstraints* constraints,
     33                     extras::Codec* orig_codec) {
     34   if (bytes.size() < kMinBytes) return JXL_FAILURE("Too few bytes");
     35 
     36   extras::PackedPixelFile ppf;
     37   if (extras::DecodeBytes(bytes, color_hints, &ppf, constraints, orig_codec)) {
     38     return ConvertPackedPixelFileToCodecInOut(ppf, pool, io);
     39   }
     40   return JXL_FAILURE("Codecs failed to decode");
     41 }
     42 
     43 Status Encode(const extras::PackedPixelFile& ppf, const extras::Codec codec,
     44               std::vector<uint8_t>* bytes, ThreadPool* pool) {
     45   bytes->clear();
     46   std::unique_ptr<extras::Encoder> encoder;
     47   switch (codec) {
     48     case extras::Codec::kPNG:
     49       encoder = extras::GetAPNGEncoder();
     50       if (encoder) {
     51         break;
     52       } else {
     53         return JXL_FAILURE("JPEG XL was built without (A)PNG support");
     54       }
     55     case extras::Codec::kJPG:
     56       encoder = extras::GetJPEGEncoder();
     57       if (encoder) {
     58         break;
     59       } else {
     60         return JXL_FAILURE("JPEG XL was built without JPEG support");
     61       }
     62     case extras::Codec::kPNM:
     63       if (ppf.info.alpha_bits > 0) {
     64         encoder = extras::GetPAMEncoder();
     65       } else if (ppf.info.num_color_channels == 1) {
     66         encoder = extras::GetPGMEncoder();
     67       } else if (ppf.info.bits_per_sample <= 16) {
     68         encoder = extras::GetPPMEncoder();
     69       } else {
     70         encoder = extras::GetPFMEncoder();
     71       }
     72       break;
     73     case extras::Codec::kPGX:
     74       encoder = extras::GetPGXEncoder();
     75       break;
     76     case extras::Codec::kGIF:
     77       return JXL_FAILURE("Encoding to GIF is not implemented");
     78     case extras::Codec::kEXR:
     79       encoder = extras::GetEXREncoder();
     80       if (encoder) {
     81         break;
     82       } else {
     83         return JXL_FAILURE("JPEG XL was built without OpenEXR support");
     84       }
     85     case extras::Codec::kJXL:
     86       // TODO(user): implement
     87       return JXL_FAILURE("Codec::kJXL is not supported yet");
     88 
     89     case extras::Codec::kUnknown:
     90       return JXL_FAILURE("Cannot encode using Codec::kUnknown");
     91   }
     92 
     93   if (!encoder) {
     94     return JXL_FAILURE("Invalid codec.");
     95   }
     96   extras::EncodedImage encoded_image;
     97   JXL_RETURN_IF_ERROR(encoder->Encode(ppf, &encoded_image, pool));
     98   JXL_ASSERT(encoded_image.bitstreams.size() == 1);
     99   *bytes = encoded_image.bitstreams[0];
    100 
    101   return true;
    102 }
    103 
    104 Status Encode(const extras::PackedPixelFile& ppf, const std::string& pathname,
    105               std::vector<uint8_t>* bytes, ThreadPool* pool) {
    106   std::string extension;
    107   const extras::Codec codec =
    108       extras::CodecFromPath(pathname, nullptr, &extension);
    109   return Encode(ppf, codec, bytes, pool);
    110 }
    111 
    112 }  // namespace jxl