Grok 20.3.2
StreamGenerator.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-2026 Grok Image Compression Inc.
3 *
4 * This source code is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License, version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This source code is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Affero General Public License for more details.
12 *
13 * You should have received a copy of the GNU Affero General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#pragma once
19
20#include <string_view>
21
22#include "grk_config_private.h"
23#include "grok.h"
24#include "S3Fetcher.h"
25#include "GSFetcher.h"
26#include "AZFetcher.h"
27#include "ADLSFetcher.h"
28#include "HTTPFetcher.h"
29
30namespace grk
31{
32
43bool detectFormat(const uint8_t* buffer, GRK_CODEC_FORMAT* fmt);
44
45#define GRK_JPEG_2000_NUM_IDENTIFIER_BYTES 22
46
48{
49public:
51 {
52 streamParams_.initial_offset = src->initial_offset;
53 streamParams_.double_buffer_len = src->double_buffer_len;
54 streamParams_.initial_double_buffer_len = src->initial_double_buffer_len;
55 streamParams_.from_network = src->from_network;
56 streamParams_.is_read_stream = src->is_read_stream;
57
58 safe_strcpy(streamParams_.file, src->file);
59 streamParams_.use_stdio = src->use_stdio;
60
61 streamParams_.buf = src->buf; // Shallow copy; allocate if deep copy needed
62 streamParams_.buf_len = src->buf_len;
63 streamParams_.buf_compressed_len = src->buf_compressed_len;
64
65 streamParams_.read_fn = src->read_fn;
66 streamParams_.write_fn = src->write_fn;
67 streamParams_.seek_fn = src->seek_fn;
68 streamParams_.free_user_data_fn = src->free_user_data_fn;
69 streamParams_.user_data = src->user_data; // Shallow copy
70 streamParams_.stream_len = src->stream_len;
71
72 safe_strcpy(streamParams_.username, src->username);
73 safe_strcpy(streamParams_.password, src->password);
74 safe_strcpy(streamParams_.bearer_token, src->bearer_token);
75 streamParams_.num_custom_headers = src->num_custom_headers;
76 for(uint8_t i = 0; i < src->num_custom_headers; ++i)
77 safe_strcpy(streamParams_.custom_headers[i], src->custom_headers[i]);
78 safe_strcpy(streamParams_.region, src->region);
79
80 safe_strcpy(streamParams_.s3_endpoint, src->s3_endpoint);
81 streamParams_.s3_use_https = src->s3_use_https;
82 streamParams_.s3_use_virtual_hosting = src->s3_use_virtual_hosting;
83 streamParams_.s3_no_sign_request = src->s3_no_sign_request;
84 streamParams_.s3_allow_insecure = src->s3_allow_insecure;
85 }
87 {
88 if(streamParams_.buf && streamParams_.buf_len)
89 {
90 return createBufferStream(streamParams_.is_read_stream);
91 }
92
93 if(streamParams_.read_fn || streamParams_.write_fn)
94 {
95 return createCallbackStream();
96 }
97
98 if(streamParams_.file[0] || streamParams_.use_stdio)
99 {
100 if(streamParams_.is_read_stream && streamParams_.file[0])
101 {
102 std::string_view file{streamParams_.file};
103 bool isNetwork = file.starts_with("http://") || file.starts_with("https://") ||
104 file.starts_with("/vsis3/") || file.starts_with("/vsicurl/") ||
105 file.starts_with("/vsiaz/") || file.starts_with("/vsiadls/") ||
106 file.starts_with("/vsigs/");
107 if(isNetwork && !streamParams_.read_fn)
108 return createCurlFetchStream();
109 }
110 return createFileStream();
111 }
112
113 grklog.error("Invalid stream parameters: no valid stream source specified.");
114 return nullptr;
115 }
116
117private:
118 static constexpr size_t DEFAULT_BUFFER_LEN = 4096;
119 static constexpr size_t DEFAULT_INITIAL_BUFFER_LEN = 512 * 1024;
120 static constexpr bool useCallbacks = false;
121
122 size_t getDoubleBufferLength(size_t configuredLength)
123 {
124 return configuredLength ? configuredLength : DEFAULT_BUFFER_LEN;
125 }
126
127 size_t getInitialDoubleBufferLength(size_t configuredLength)
128 {
129 return configuredLength ? configuredLength : DEFAULT_INITIAL_BUFFER_LEN;
130 }
131
132 // CurlSyncFetch Stream Creation (handles both HTTP/HTTPS and /vsis3/)
134
136
138
139 IStream* createBufferStream(bool isReadStream)
140 {
141 auto stream = memStreamCreate(streamParams_.buf, streamParams_.buf_len, false, nullptr,
142 GRK_CODEC_FORMAT::GRK_CODEC_UNK, isReadStream);
143 if(!stream)
144 {
145 grklog.error("Unable to create memory stream.");
146 }
147 return stream;
148 }
149
151 {
153 stream->seek(0);
154 if(!stream->read(buf, nullptr, GRK_JPEG_2000_NUM_IDENTIFIER_BYTES))
155 {
156 return false;
157 }
158
160 if(!detectFormat(buf, &fmt))
161 {
162 grklog.error("Unable to detect codec format.");
163 return false;
164 }
165
166 stream->seek(0);
167 stream->setFormat(fmt);
168 return true;
169 }
170
171 // File operation helpers
172 static size_t grkReadFromFile(uint8_t* buffer, size_t numBytes, void* p_file)
173 {
174 return fread(buffer, 1, numBytes, (FILE*)p_file);
175 }
176
177 static uint64_t getDataLengthFromFile(void* filePtr)
178 {
179 auto file = (FILE*)filePtr;
180 GRK_FSEEK(file, 0, SEEK_END);
181 int64_t file_length = (int64_t)GRK_FTELL(file);
182 GRK_FSEEK(file, 0, SEEK_SET);
183 return (uint64_t)file_length;
184 }
185
186 static size_t grkWriteToFile(const uint8_t* buffer, size_t numBytes, void* p_file)
187 {
188 return fwrite(buffer, 1, numBytes, (FILE*)p_file);
189 }
190
191 static bool grkSeekInFile(uint64_t numBytes, void* p_user_data)
192 {
193 if(numBytes > INT64_MAX)
194 return false;
195 return GRK_FSEEK((FILE*)p_user_data, (int64_t)numBytes, SEEK_SET) ? false : true;
196 }
197
198 static void grkFreeFile(void* p_user_data)
199 {
200 if(p_user_data)
201 fclose((FILE*)p_user_data);
202 }
203
204private:
206
207 template<size_t N>
208 void safe_strcpy(char (&dest)[N], const char* src)
209 {
210 if(!src || !src[0])
211 return;
212 size_t len = strnlen(src, N - 1);
213 memcpy(dest, src, len);
214 dest[len] = '\0';
215 }
216};
217
218} // namespace grk
#define GRK_FSEEK(stream, offset, whence)
Definition CodingParams.cpp:26
#define GRK_FTELL(stream)
Definition CodingParams.cpp:27
#define GRK_JPEG_2000_NUM_IDENTIFIER_BYTES
Definition StreamGenerator.h:45
StreamGenerator(grk_stream_params *src)
Definition StreamGenerator.h:50
grk_stream_params streamParams_
Definition StreamGenerator.h:205
static constexpr size_t DEFAULT_INITIAL_BUFFER_LEN
Definition StreamGenerator.h:119
IStream * createCallbackStream(void)
Definition StreamGenerator.cpp:36
void safe_strcpy(char(&dest)[N], const char *src)
Definition StreamGenerator.h:208
size_t getDoubleBufferLength(size_t configuredLength)
Definition StreamGenerator.h:122
static bool grkSeekInFile(uint64_t numBytes, void *p_user_data)
Definition StreamGenerator.h:191
static uint64_t getDataLengthFromFile(void *filePtr)
Definition StreamGenerator.h:177
static size_t grkWriteToFile(const uint8_t *buffer, size_t numBytes, void *p_file)
Definition StreamGenerator.h:186
static constexpr bool useCallbacks
Definition StreamGenerator.h:120
IStream * createCurlFetchStream(void)
Definition StreamGenerator.cpp:113
IStream * create(void)
Definition StreamGenerator.h:86
size_t getInitialDoubleBufferLength(size_t configuredLength)
Definition StreamGenerator.h:127
IStream * createBufferStream(bool isReadStream)
Definition StreamGenerator.h:139
IStream * createFileStream(void)
Definition StreamGenerator.cpp:71
static size_t grkReadFromFile(uint8_t *buffer, size_t numBytes, void *p_file)
Definition StreamGenerator.h:172
static void grkFreeFile(void *p_user_data)
Definition StreamGenerator.h:198
static constexpr size_t DEFAULT_BUFFER_LEN
Definition StreamGenerator.h:118
bool validateStream(IStream *stream)
Definition StreamGenerator.h:150
enum _GRK_CODEC_FORMAT GRK_CODEC_FORMAT
Grok Supported JPEG 2000 formats.
ResWindow.
Definition CompressedChunkCache.h:36
ILogger & grklog
Definition Logger.cpp:24
IStream * memStreamCreate(uint8_t *buf, size_t len, bool ownsBuffer, grk_stream_free_user_data_fn freeCallback, GRK_CODEC_FORMAT format, bool isReadStream)
Create stream from buffer.
Definition MemStream.cpp:153
bool detectFormat(const uint8_t *buffer, GRK_CODEC_FORMAT *fmt)
Detect JPEG 2000 format from buffer Format is either GRK_FMT_J2K or GRK_FMT_JP2.
Definition MemStream.cpp:39
Definition IStream.h:60
virtual bool seek(uint64_t offset)=0
Seek bytes from the stream (absolute).
virtual size_t read(uint8_t *buffer, uint8_t **zero_copy_buffer, size_t len)=0
Read bytes from stream.
virtual void setFormat(GRK_CODEC_FORMAT format)=0
Stores codec format J2K/JP2/MJ2.
JPEG 2000 stream parameters There are three methods of streaming: by file, buffer or callback Client ...