OpenJPH
Open-source implementation of JPEG2000 Part-15
Loading...
Searching...
No Matches
ojph_file.cpp
Go to the documentation of this file.
1//***************************************************************************/
2// This software is released under the 2-Clause BSD license, included
3// below.
4//
5// Copyright (c) 2019, Aous Naman
6// Copyright (c) 2019, Kakadu Software Pty Ltd, Australia
7// Copyright (c) 2019, The University of New South Wales, Australia
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// 1. Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15//
16// 2. Redistributions in binary form must reproduce the above copyright
17// notice, this list of conditions and the following disclaimer in the
18// documentation and/or other materials provided with the distribution.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31//***************************************************************************/
32// This file is part of the OpenJPH software implementation.
33// File: ojph_file.cpp
34// Author: Aous Naman
35// Date: 28 August 2019
36//***************************************************************************/
37
38
42
43#include <cassert>
44#include <cstddef>
45
46#include "ojph_mem.h"
47#include "ojph_file.h"
48#include "ojph_message.h"
49
50namespace ojph {
51
53 //
54 //
55 //
56 //
57 //
59
61 void j2c_outfile::open(const char *filename)
62 {
63 assert(fh == 0);
64 fh = fopen(filename, "wb");
65 if (fh == NULL)
66 OJPH_ERROR(0x00060001, "failed to open %s for writing", filename);
67 }
68
70 size_t j2c_outfile::write(const void *ptr, size_t size)
71 {
72 assert(fh);
73 return fwrite(ptr, 1, size, fh);
74 }
75
78 {
79 assert(fh);
80 return ojph_ftell(fh);
81 }
82
85 {
86 assert(fh);
87 fflush(fh);
88 }
89
92 {
93 assert(fh);
94 fclose(fh);
95 fh = NULL;
96 }
97
98 //*************************************************************************/
99 // mem_outfile
100 //*************************************************************************/
101
104 {
105 is_open = clear_mem = false;
106 buf_size = used_size = 0;
107 buf = cur_ptr = NULL;
108 }
109
112 {
113 if (buf)
115 is_open = clear_mem = false;
116 buf_size = used_size = 0;
117 buf = cur_ptr = NULL;
118 }
119
121 void mem_outfile::open(size_t initial_size, bool clear_mem)
122 {
123 assert(this->is_open == false);
124 assert(this->cur_ptr == this->buf);
125
126 // do initial buffer allocation or buffer expansion
127 this->is_open = true;
128 this->clear_mem = clear_mem;
129 expand_storage(initial_size, this->clear_mem);
130 this->used_size = 0;
131 this->cur_ptr = this->buf;
132 }
133
136 is_open = false;
137 cur_ptr = buf;
138 }
139
144 {
145 if (origin == OJPH_SEEK_SET)
146 ; // do nothing
147 else if (origin == OJPH_SEEK_CUR)
148 offset += tell();
149 else if (origin == OJPH_SEEK_END)
150 offset += (si64)used_size;
151 else {
152 assert(0);
153 return -1;
154 }
155
156 if (offset < 0) // offset before the start of file
157 return -1;
158
159 expand_storage((size_t)offset, false); // See if expansion is needed
160
161 cur_ptr = buf + offset;
162 return 0;
163 }
164
167 size_t mem_outfile::write(const void *ptr, size_t new_size)
168 {
169 assert(this->is_open);
170 assert(this->buf_size);
171 assert(this->buf);
172 assert(this->cur_ptr);
173
174 // expand buffer if needed to make sure it has room for this write
175 size_t needed_size = (size_t)tell() + new_size; //needed size
176 expand_storage(needed_size, false);
177
178 // copy bytes into buffer and adjust cur_ptr
179 memcpy(this->cur_ptr, ptr, new_size);
180 cur_ptr += new_size;
181 used_size = ojph_max(used_size, (size_t)tell());
182
183 return new_size;
184 }
185
187 void mem_outfile::write_to_file(const char *file_name) const
188 {
189 assert(is_open == false);
190 FILE *f = fopen(file_name, "wb");
191 if (f == NULL)
192 OJPH_ERROR(0x00060003, "failed to open %s for writing", file_name);
193 if (f != NULL)
194 if (fwrite(this->buf, 1, used_size, f) != used_size)
195 OJPH_ERROR(0x00060004, "failed writing to %s", file_name);
196 fclose(f);
197 }
198
200 void mem_outfile::expand_storage(size_t needed_size, bool clear_all)
201 {
202 if (needed_size > buf_size)
203 {
204 needed_size += (needed_size + 1) >> 1; // x1.5
205 // expand buffer to multiples of (ALIGNED_ALLOC_MASK + 1)
206 needed_size = (needed_size + ALIGNED_ALLOC_MASK) & (~ALIGNED_ALLOC_MASK);
207
208 ui8* new_buf;
209 new_buf = (ui8*)ojph_aligned_malloc(ALIGNED_ALLOC_MASK + 1, needed_size);
210 if (new_buf == NULL)
211 OJPH_ERROR(0x00060005, "failed to allocate memory (%zu bytes)",
212 needed_size);
213
214 if (this->buf != NULL)
215 {
216 if (!clear_all)
217 memcpy(new_buf, this->buf, used_size);
218 ojph_aligned_free(this->buf);
219 }
220 this->cur_ptr = new_buf + tell();
221 this->buf = new_buf;
222
223 if (clear_mem && !clear_all) // will be cleared later
224 memset(this->buf + buf_size, 0, needed_size - this->buf_size);
225 this->buf_size = needed_size;
226 }
227 if (clear_all)
228 memset(this->buf, 0, this->buf_size);
229 }
230
231
233 //
234 //
235 //
236 //
237 //
239
241 void j2c_infile::open(const char *filename)
242 {
243 assert(fh == NULL);
244 fh = fopen(filename, "rb");
245 if (fh == NULL)
246 OJPH_ERROR(0x00060002, "failed to open %s for reading", filename);
247 }
248
250 size_t j2c_infile::read(void *ptr, size_t size)
251 {
252 assert(fh);
253 return fread(ptr, 1, size, fh);
254 }
255
257 int j2c_infile::seek(si64 offset, enum infile_base::seek origin)
258 {
259 assert(fh);
260 return ojph_fseek(fh, offset, origin);
261 }
262
265 {
266 assert(fh);
267 return ojph_ftell(fh);
268 }
269
272 {
273 assert(fh);
274 fclose(fh);
275 fh = NULL;
276 }
277
278
280 //
281 //
282 //
283 //
284 //
286
288 void mem_infile::open(const ui8* data, size_t size)
289 {
290 assert(this->data == NULL);
291 cur_ptr = this->data = data;
292 this->size = size;
293 }
294
296 size_t mem_infile::read(void *ptr, size_t size)
297 {
298 std::ptrdiff_t bytes_left = (data + this->size) - cur_ptr;
299 if (bytes_left > 0)
300 {
301 size_t bytes_to_read = ojph_min(size, (size_t)bytes_left);
302 memcpy(ptr, cur_ptr, bytes_to_read);
303 cur_ptr += bytes_to_read;
304 return bytes_to_read;
305 }
306 else
307 return 0;
308 }
309
311 int mem_infile::seek(si64 offset, enum infile_base::seek origin)
312 {
313 int result = -1;
314 if (origin == OJPH_SEEK_SET)
315 {
316 if (offset >= 0 && (size_t)offset <= size)
317 {
318 cur_ptr = data + offset;
319 result = 0;
320 }
321 }
322 else if (origin == OJPH_SEEK_CUR)
323 {
324 si64 bytes_off = (si64)(cur_ptr - data) + offset;
325 if (bytes_off >= 0 && (size_t)bytes_off <= size)
326 {
327 cur_ptr = data + bytes_off;
328 result = 0;
329 }
330 }
331 else if (origin == OJPH_SEEK_END)
332 {
333 if (offset <= 0 && (std::ptrdiff_t)size + offset >= 0)
334 {
335 cur_ptr = data + size + offset;
336 result = 0;
337 }
338 }
339 else
340 assert(0);
341
342 return result;
343 }
344
345
346}
void close() override
void open(const char *filename)
size_t read(void *ptr, size_t size) override
si64 tell() override
void flush() override
Definition ojph_file.cpp:84
void close() override
Definition ojph_file.cpp:91
si64 tell() override
Definition ojph_file.cpp:77
void open(const char *filename)
Definition ojph_file.cpp:61
size_t write(const void *ptr, size_t size) override
Definition ojph_file.cpp:70
const ui8 * cur_ptr
Definition ojph_file.h:305
size_t read(void *ptr, size_t size) override
void open(const ui8 *data, size_t size)
const ui8 * data
Definition ojph_file.h:305
si64 tell() override
Call this function to know the file size (i.e., number of bytes used to store the file).
Definition ojph_file.h:163
static const size_t ALIGNED_ALLOC_MASK
Definition ojph_file.h:242
size_t write(const void *ptr, size_t size) override
Call this function to write data to the memory file.
void expand_storage(size_t new_size, bool clear_all)
This function expands storage by x1.5 needed space.
void open(size_t initial_size=65536, bool clear_mem=false)
Call this function to open a memory file.
~mem_outfile() override
void close() override
void write_to_file(const char *file_name) const
Call this function to write the memory file data to a file.
int ojph_fseek(FILE *stream, si64 offset, int origin)
Definition ojph_file.h:61
void * ojph_aligned_malloc(size_t alignment, size_t size)
Definition ojph_mem.h:63
si64 ojph_ftell(FILE *stream)
Definition ojph_file.h:66
int64_t si64
Definition ojph_defs.h:57
uint8_t ui8
Definition ojph_defs.h:50
void ojph_aligned_free(void *pointer)
Definition ojph_mem.h:68
#define ojph_max(a, b)
Definition ojph_defs.h:73
#define ojph_min(a, b)
Definition ojph_defs.h:76
#define OJPH_ERROR(t,...)