Coverage Report

Created: 2025-11-16 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/extras/codec.cc
Line
Count
Source
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 <cstddef>
9
#include <cstdint>
10
#include <memory>
11
#include <string>
12
#include <vector>
13
14
#include "lib/extras/codec_in_out.h"
15
#include "lib/extras/dec/color_hints.h"
16
#include "lib/extras/dec/decode.h"
17
#include "lib/extras/enc/apng.h"
18
#include "lib/extras/enc/encode.h"
19
#include "lib/extras/enc/exr.h"
20
#include "lib/extras/enc/jpg.h"
21
#include "lib/extras/enc/pgx.h"
22
#include "lib/extras/enc/pnm.h"
23
#include "lib/extras/packed_image.h"
24
#include "lib/extras/packed_image_convert.h"
25
#include "lib/jxl/base/data_parallel.h"
26
#include "lib/jxl/base/span.h"
27
#include "lib/jxl/base/status.h"
28
29
namespace jxl {
30
namespace {
31
32
// Any valid encoding is larger (ensures codecs can read the first few bytes)
33
constexpr size_t kMinBytes = 9;
34
35
}  // namespace
36
37
Status SetFromBytes(const Span<const uint8_t> bytes,
38
                    const extras::ColorHints& color_hints, CodecInOut* io,
39
                    ThreadPool* pool, const SizeConstraints* constraints,
40
23.5k
                    extras::Codec* orig_codec) {
41
23.5k
  if (bytes.size() < kMinBytes) return JXL_FAILURE("Too few bytes");
42
43
23.5k
  extras::PackedPixelFile ppf;
44
23.5k
  if (extras::DecodeBytes(bytes, color_hints, &ppf, constraints, orig_codec,
45
23.5k
                          io->memory_manager)) {
46
1.29k
    return ConvertPackedPixelFileToCodecInOut(ppf, pool, io);
47
1.29k
  }
48
22.2k
  return JXL_FAILURE("Codecs failed to decode");
49
23.5k
}
50
51
Status Encode(const extras::PackedPixelFile& ppf, const extras::Codec codec,
52
0
              std::vector<uint8_t>* bytes, ThreadPool* pool) {
53
0
  bytes->clear();
54
0
  std::unique_ptr<extras::Encoder> encoder;
55
0
  switch (codec) {
56
0
    case extras::Codec::kPNG:
57
0
      encoder = extras::GetAPNGEncoder();
58
0
      if (encoder) {
59
0
        break;
60
0
      } else {
61
0
        return JXL_FAILURE("JPEG XL was built without (A)PNG support");
62
0
      }
63
0
    case extras::Codec::kJPG:
64
0
      encoder = extras::GetJPEGEncoder();
65
0
      if (encoder) {
66
0
        break;
67
0
      } else {
68
0
        return JXL_FAILURE("JPEG XL was built without JPEG support");
69
0
      }
70
0
    case extras::Codec::kPNM:
71
0
      if (ppf.info.alpha_bits > 0) {
72
0
        encoder = extras::GetPAMEncoder();
73
0
      } else if (ppf.info.num_color_channels == 1) {
74
0
        encoder = extras::GetPGMEncoder();
75
0
      } else if (ppf.info.bits_per_sample <= 16) {
76
0
        encoder = extras::GetPPMEncoder();
77
0
      } else {
78
0
        encoder = extras::GetPFMEncoder();
79
0
      }
80
0
      break;
81
0
    case extras::Codec::kPGX:
82
0
      encoder = extras::GetPGXEncoder();
83
0
      break;
84
0
    case extras::Codec::kGIF:
85
0
      return JXL_FAILURE("Encoding to GIF is not implemented");
86
0
    case extras::Codec::kEXR:
87
0
      encoder = extras::GetEXREncoder();
88
0
      if (encoder) {
89
0
        break;
90
0
      } else {
91
0
        return JXL_FAILURE("JPEG XL was built without OpenEXR support");
92
0
      }
93
0
    case extras::Codec::kJXL:
94
      // TODO(user): implement
95
0
      return JXL_FAILURE("Codec::kJXL is not supported yet");
96
97
0
    case extras::Codec::kUnknown:
98
0
      return JXL_FAILURE("Cannot encode using Codec::kUnknown");
99
0
  }
100
101
0
  if (!encoder) {
102
0
    return JXL_FAILURE("Invalid codec.");
103
0
  }
104
0
  extras::EncodedImage encoded_image;
105
0
  JXL_RETURN_IF_ERROR(encoder->Encode(ppf, &encoded_image, pool));
106
0
  JXL_ENSURE(encoded_image.bitstreams.size() == 1);
107
0
  *bytes = encoded_image.bitstreams[0];
108
109
0
  return true;
110
0
}
111
112
Status Encode(const extras::PackedPixelFile& ppf, const std::string& pathname,
113
0
              std::vector<uint8_t>* bytes, ThreadPool* pool) {
114
0
  std::string extension;
115
0
  const extras::Codec codec =
116
0
      extras::CodecFromPath(pathname, nullptr, &extension);
117
0
  return Encode(ppf, codec, bytes, pool);
118
0
}
119
120
}  // namespace jxl