Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_buffer_stream.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2005-2006 Cyrille Berger <cberger@cberger.net>
3 * SPDX-FileCopyrightText: 2022 L. E. Segovia <amy@amyspark.me>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#include "kis_buffer_stream.h"
9
10#include <kis_debug.h>
11
13 uint16_t depth,
14 tsize_t lineSize)
15
16 : KisBufferStreamBase(depth)
17 , m_src(src)
18 , m_srcIt(src)
19 , m_posinc(8)
20 , m_lineSize(lineSize)
21{
22 KIS_ASSERT(depth <= 32);
23 restart();
24}
25
33
35{
36 KIS_ASSERT(lineNumber >= 0);
37 moveToPos(0, lineNumber);
38}
39
40void KisBufferStreamContigBase::moveToPos(tsize_t x, tsize_t y)
41{
42 KIS_ASSERT(x >= 0 && y >= 0);
44 m_lineOffset = (x * m_depth) / 8;
46 m_posinc = 8;
47}
48
50{
51 return (m_lineOffset * 8) / m_depth;
52}
53
55{
56 return m_lineNumber;
57}
58
60{
61 return (m_lineSize * 8) / m_depth;
62}
63
65{
66 uint16_t remain = m_depth;
67 uint32_t value = 0 ;
68 while (remain > 0) {
69 uint16_t toread = remain;
70 if (toread > m_posinc) toread = m_posinc;
71 remain -= toread;
72 m_posinc -= toread;
73 value = (value << toread) | (((*m_srcIt) >> (m_posinc)) & ((1 << toread) - 1));
74 if (m_posinc == 0) {
75 m_srcIt++;
76 m_lineOffset++; // we consumed a byte
77 m_posinc = 8;
78 }
79 }
80 if (m_lineOffset >= m_lineSize) {
81 m_lineNumber += 1;
82 m_lineOffset = 0;
83 }
84 return value;
85}
86
88{
89 uint16_t remain = m_depth;
90 uint32_t value = 0;
91 while (remain > 0) {
92 uint16_t toread = remain;
93 if (toread > m_posinc) toread = m_posinc;
94 remain -= toread;
95 m_posinc -= toread;
96 value = (value) | ((((*m_srcIt) >> (m_posinc)) & ((1 << toread) - 1U)) << (m_depth - 8U - remain));
97 if (m_posinc == 0) {
98 m_srcIt++;
99 m_lineOffset++; // we consumed a byte
100 m_posinc = 8U;
101 }
102 }
103 if (m_lineOffset >= m_lineSize) {
104 m_lineNumber += 1;
105 m_lineOffset = 0;
106 }
107 return value;
108}
109
111{
112 uint16_t remain = m_depth;
113 uint32_t value = 0;
114 while (remain > 0) {
115 uint16_t toread = remain;
116 if (toread > m_posinc)
117 toread = m_posinc;
118 remain -= toread;
119 m_posinc = m_posinc - toread;
120 if (remain < 32U) {
121 value |= (((*m_srcIt >> m_posinc) & ((1U << toread) - 1U)) << (24U - remain));
122 }
123 if (m_posinc == 0) {
124 m_srcIt++;
125 m_lineOffset++; // we consumed a byte
126 m_posinc = 8U;
127 }
128 }
129 if (m_lineOffset >= m_lineSize) {
130 m_lineNumber += 1;
131 m_lineOffset = 0;
132 }
133 return value;
134}
135
136KisBufferStreamSeparate::KisBufferStreamSeparate(uint8_t **srcs, uint16_t nb_samples, uint16_t depth, tsize_t *lineSize)
137 : KisBufferStreamBase(depth)
138 , m_nb_samples(nb_samples)
139{
140 if (depth < 16) {
141 for (uint16_t i = 0; i < m_nb_samples; i++) {
142 streams.push_back(
144 srcs[i],
145 depth,
146 lineSize[i]));
147 }
148 } else if (depth < 32) {
149 for (uint16_t i = 0; i < m_nb_samples; i++) {
150 streams.push_back(
152 srcs[i],
153 depth,
154 lineSize[i]));
155 }
156 } else {
157 for (uint16_t i = 0; i < m_nb_samples; i++) {
158 streams.push_back(
160 srcs[i],
161 depth,
162 lineSize[i]));
163 }
164 }
165 restart();
166}
167
169{
170 const uint32_t value = streams[m_current_sample]->nextValue();
173 return value;
174}
175
177{
179 for (const auto &stream : streams) {
180 stream->restart();
181 }
182}
183
185{
186 KIS_ASSERT(lineNumber >= 0);
187 moveToPos(0, lineNumber);
188}
189
190void KisBufferStreamSeparate::moveToPos(tsize_t x, tsize_t y)
191{
192 for (const auto &stream : streams) {
193 stream->moveToPos(x, y);
194 }
195}
196
198{
199 return streams[m_current_sample]->x();
200}
201
203{
204 return streams[m_current_sample]->y();
205}
206
208{
209 return streams[m_current_sample]->width();
210}
211
213 uint8_t **srcs,
214 uint16_t nb_samples,
215 uint16_t depth,
216 tsize_t *lineSize,
217 uint16_t hsubsample,
218 uint16_t vsubsample)
219 : KisBufferStreamSeparate(srcs, nb_samples, depth, lineSize)
220 , m_hsubsample(hsubsample)
221 , m_vsubsample(vsubsample)
222{
223}
224
226{
227 uint32_t value = streams[m_currentPlane]->nextValue();
228 if (m_currentPlane == 0) {
230 if (m_current_sample % m_hsubsample == 0) {
232 // Fix up the position of the luminance plane
233 // If it's already 0, the cursor has already looped (correctly)
234 // to the next line
235 if (streams[m_currentPlane]->x() != 0) {
236 streams[m_currentPlane]->moveToPos(
239 }
240 // Move to Cb/Cr
241 m_currentPlane += 1;
243 } else {
244 // Go to next line
245 // If the position is already 0, we need to correct the row
246 // AND column
247 if (streams[m_currentPlane]->x() != 0) {
248 streams[m_currentPlane]->moveToPos(
250 streams[m_currentPlane]->y() + 1);
251 } else {
252 streams[m_currentPlane]->moveToPos(
255 }
256 }
257 }
258 } else if (m_currentPlane < m_nb_samples - 1) {
259 m_currentPlane += 1;
260 } else {
261 m_currentPlane = 0;
262 }
263 return value;
264}
265
267{
268 // Needs to subsample
269 for (uint16_t i = 0; i < m_nb_samples; i++) {
270 const tsize_t realX = i == 0 ? x : x / m_hsubsample;
271 const tsize_t realY = i == 0 ? y : y / m_vsubsample;
272 streams.at(i)->moveToPos(realX, realY);
273 }
274}
275
277{
278 return streams[0]->x();
279}
280
282{
283 return streams[0]->y();
284}
float value(const T *src, size_t ch)
void moveToLine(tsize_t lineNumber) override
void moveToPos(tsize_t x, tsize_t y) override
KisBufferStreamContigBase(uint8_t *src, uint16_t depth, tsize_t lineSize)
tsize_t y() const override
tsize_t width() const override
tsize_t x() const override
void moveToPos(tsize_t x, tsize_t y) override
KisBufferStreamInterleaveUpsample(uint8_t **srcs, uint16_t nb_samples, uint16_t depth, tsize_t *lineSize, uint16_t hsubsample, uint16_t vsubsample)
tsize_t y() const override
uint32_t nextValue() override
void moveToLine(tsize_t lineNumber) override
KisBufferStreamSeparate(uint8_t **srcs, uint16_t nb_samples, uint16_t depth, tsize_t *lineSize)
tsize_t x() const override
QVector< QSharedPointer< KisBufferStreamBase > > streams
tsize_t width() const override
void moveToPos(tsize_t x, tsize_t y) override
#define KIS_ASSERT(cond)
Definition kis_assert.h:33