RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
BitVacuumerJPEG.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2024 Roman Lebedev
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#pragma once
22
23#include "adt/Array1DRef.h"
24#include "adt/Invariant.h"
27#include "io/Endianness.h"
28#include <cstddef>
29#include <cstdint>
30#include <numeric>
31
32namespace rawspeed {
33
34template <typename OutputIterator> class BitVacuumerJPEG;
35
36template <typename OutputIterator>
37struct BitVacuumerTraits<BitVacuumerJPEG<OutputIterator>> final {
38 static constexpr BitOrder Tag = BitOrder::JPEG;
39
40 static constexpr bool canUseWithPrefixCodeEncoder = true;
41};
42
43template <typename OutputIterator>
44class BitVacuumerJPEG final
45 : public BitVacuumer<BitVacuumerJPEG<OutputIterator>, OutputIterator> {
48
49 friend void Base::drain(); // Allow it to actually call `drainImpl()`.
50
51 void drainImpl() {
54
55 constexpr int StreamChunkBitwidth =
57 static_assert(Base::chunk_bitwidth >= StreamChunkBitwidth);
58 static_assert(Base::chunk_bitwidth % StreamChunkBitwidth == 0);
59 constexpr int NumChunksNeeded = Base::chunk_bitwidth / StreamChunkBitwidth;
60 static_assert(NumChunksNeeded == 1);
61
63 Base::cache.peek(StreamChunkBitwidth));
64 Base::cache.skip(StreamChunkBitwidth);
65
66 const auto bytes = Array1DRef<const std::byte>(Array1DRef(&chunk, 1));
67
68 // short-cut path for the most common case (no FF marker in the next 4
69 // bytes) this is slightly faster than the else-case alone.
70 if (std::accumulate(bytes.begin(), bytes.end(), true,
71 [](bool b, std::byte byte) {
72 return b && (byte != std::byte{0xFF});
73 })) {
75 &chunk, StreamTraits::ChunkEndianness != Endianness::little);
76 *Base::output = chunk;
78 return;
79 }
80
82 &chunk, StreamTraits::ChunkEndianness != getHostEndianness());
83
84 for (const auto byte : bytes) {
85 *Base::output = static_cast<uint8_t>(byte);
87 if (static_cast<uint8_t>(byte) == 0xFF) {
88 *Base::output = uint8_t(0x00); // Stuffing byte
90 }
91 }
92 }
93
94public:
95 using Base::Base;
96};
97
98} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
typename Base::StreamTraits StreamTraits
BitVacuumer< BitVacuumerJPEG< OutputIterator >, OutputIterator > Base
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
int8_t getByteSwapped(int8_t v)
Definition Endianness.h:75
Endianness getHostEndianness()
Definition Endianness.h:51
constexpr unsigned RAWSPEED_READNONE bitwidth(T unused={})
Definition Bit.h:43
Array1DRef(T *data_, int numElts_) -> Array1DRef< T >