OpenJPH
Open-source implementation of JPEG2000 Part-15
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
43#include <cassert>
44#include <cstddef>
45
46#include "ojph_file.h"
47#include "ojph_message.h"
48
49namespace ojph {
50
52 //
53 //
54 //
55 //
56 //
58
60 void j2c_outfile::open(const char *filename)
61 {
62 assert(fh == 0);
63 fh = fopen(filename, "wb");
64 if (fh == NULL)
65 OJPH_ERROR(0x00060001, "failed to open %s for writing", filename);
66 }
67
69 size_t j2c_outfile::write(const void *ptr, size_t size)
70 {
71 assert(fh);
72 return fwrite(ptr, 1, size, fh);
73 }
74
77 {
78 assert(fh);
79 return ojph_ftell(fh);
80 }
81
84 {
85 assert(fh);
86 fflush(fh);
87 }
88
91 {
92 assert(fh);
93 fclose(fh);
94 fh = NULL;
95 }
96
97 //*************************************************************************/
98 // mem_outfile
99 //*************************************************************************/
100
103 {
104 is_open = clear_mem = false;
105 buf_size = used_size = 0;
106 buf = cur_ptr = NULL;
107 }
108
111 {
112 if (buf)
113 free(buf);
114 is_open = clear_mem = false;
115 buf_size = used_size = 0;
116 buf = cur_ptr = NULL;
117 }
118
120 void mem_outfile::open(size_t initial_size, bool clear_mem)
121 {
122 assert(this->is_open == false);
123 assert(this->cur_ptr == this->buf);
124
125 // do initial buffer allocation or buffer expansion
126 this->is_open = true;
127 this->clear_mem = clear_mem;
128 expand_storage(initial_size, this->clear_mem);
129 this->used_size = 0;
130 this->cur_ptr = this->buf;
131 }
132
135 is_open = false;
136 cur_ptr = buf;
137 }
138
143 {
144 if (origin == OJPH_SEEK_SET)
145 ; // do nothing
146 else if (origin == OJPH_SEEK_CUR)
147 offset += tell();
148 else if (origin == OJPH_SEEK_END)
149 offset += (si64)buf_size;
150 else {
151 assert(0);
152 return -1;
153 }
154
155 if (offset >= 0)
156 expand_storage((size_t)offset, false);
157 else
158 return -1;
159
160 cur_ptr = buf + offset;
161 return 0;
162 }
163
166 size_t mem_outfile::write(const void *ptr, size_t new_size)
167 {
168 assert(this->is_open);
169 assert(this->buf_size);
170 assert(this->buf);
171 assert(this->cur_ptr);
172
173 // expand buffer if needed to make sure it has room for this write
174 size_t needed_size = (size_t)tell() + new_size; //needed size
175 expand_storage(needed_size, false);
176
177 // copy bytes into buffer and adjust cur_ptr
178 memcpy(this->cur_ptr, ptr, new_size);
179 cur_ptr += new_size;
180 used_size = ojph_max(used_size, (size_t)tell());
181
182 return new_size;
183 }
184
186 void mem_outfile::write_to_file(const char *file_name) const
187 {
188 assert(is_open == false);
189 FILE *f = fopen(file_name, "wb");
190 if (f == NULL)
191 OJPH_ERROR(0x00060003, "failed to open %s for writing", file_name);
192 if (f != NULL)
193 if (fwrite(this->buf, 1, used_size, f) != used_size)
194 OJPH_ERROR(0x00060004, "failed writing to %s", file_name);
195 fclose(f);
196 }
197
199 void mem_outfile::expand_storage(size_t needed_size, bool clear_all)
200 {
201 needed_size += (needed_size + 1) >> 1; // x1.5
202 if (needed_size > buf_size)
203 {
204 si64 used_size = tell(); // current used size
205
206 if (this->buf)
207 this->buf = (ui8*)realloc(this->buf, needed_size);
208 else
209 this->buf = (ui8*)malloc(needed_size);
210
211 if (clear_mem && !clear_all) // will be cleared later
212 memset(this->buf + buf_size, 0, needed_size - this->buf_size);
213
214 this->buf_size = needed_size;
215 this->cur_ptr = this->buf + used_size;
216 }
217 if (clear_all)
218 memset(this->buf, 0, this->buf_size);
219 }
220
221
223 //
224 //
225 //
226 //
227 //
229
231 void j2c_infile::open(const char *filename)
232 {
233 assert(fh == NULL);
234 fh = fopen(filename, "rb");
235 if (fh == NULL)
236 OJPH_ERROR(0x00060002, "failed to open %s for reading", filename);
237 }
238
240 size_t j2c_infile::read(void *ptr, size_t size)
241 {
242 assert(fh);
243 return fread(ptr, 1, size, fh);
244 }
245
247 int j2c_infile::seek(si64 offset, enum infile_base::seek origin)
248 {
249 assert(fh);
250 return ojph_fseek(fh, offset, origin);
251 }
252
255 {
256 assert(fh);
257 return ojph_ftell(fh);
258 }
259
262 {
263 assert(fh);
264 fclose(fh);
265 fh = NULL;
266 }
267
268
270 //
271 //
272 //
273 //
274 //
276
278 void mem_infile::open(const ui8* data, size_t size)
279 {
280 assert(this->data == NULL);
281 cur_ptr = this->data = data;
282 this->size = size;
283 }
284
286 size_t mem_infile::read(void *ptr, size_t size)
287 {
288 std::ptrdiff_t bytes_left = (data + this->size) - cur_ptr;
289 if (bytes_left > 0)
290 {
291 size_t bytes_to_read = ojph_min(size, (size_t)bytes_left);
292 memcpy(ptr, cur_ptr, bytes_to_read);
293 cur_ptr += bytes_to_read;
294 return bytes_to_read;
295 }
296 else
297 return 0;
298 }
299
301 int mem_infile::seek(si64 offset, enum infile_base::seek origin)
302 {
303 int result = -1;
304 if (origin == OJPH_SEEK_SET)
305 {
306 if (offset >= 0 && (size_t)offset <= size)
307 {
308 cur_ptr = data + offset;
309 result = 0;
310 }
311 }
312 else if (origin == OJPH_SEEK_CUR)
313 {
314 std::ptrdiff_t bytes_off = cur_ptr - data; bytes_off += offset;
315 if (bytes_off >= 0 && (size_t)bytes_off <= size)
316 {
317 cur_ptr = data + bytes_off;
318 result = 0;
319 }
320 }
321 else if (origin == OJPH_SEEK_END)
322 {
323 if (offset <= 0 && (std::ptrdiff_t)size + offset >= 0)
324 {
325 cur_ptr = data + size + offset;
326 result = 0;
327 }
328 }
329 else
330 assert(0);
331
332 return result;
333 }
334
335
336}
void close() override
Definition: ojph_file.cpp:261
void open(const char *filename)
Definition: ojph_file.cpp:231
size_t read(void *ptr, size_t size) override
Definition: ojph_file.cpp:240
si64 tell() override
Definition: ojph_file.cpp:254
void flush() override
Definition: ojph_file.cpp:83
void close() override
Definition: ojph_file.cpp:90
si64 tell() override
Definition: ojph_file.cpp:76
void open(const char *filename)
Definition: ojph_file.cpp:60
size_t write(const void *ptr, size_t size) override
Definition: ojph_file.cpp:69
const ui8 * cur_ptr
Definition: ojph_file.h:287
size_t read(void *ptr, size_t size) override
Definition: ojph_file.cpp:286
void open(const ui8 *data, size_t size)
Definition: ojph_file.cpp:278
const ui8 * data
Definition: ojph_file.h:287
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
size_t write(const void *ptr, size_t size) override
Call this function to write data to the memory file.
Definition: ojph_file.cpp:166
void expand_storage(size_t new_size, bool clear_all)
This function expands storage by x1.5 needed space.
Definition: ojph_file.cpp:199
void open(size_t initial_size=65536, bool clear_mem=false)
Call this function to open a memory file.
Definition: ojph_file.cpp:120
~mem_outfile() override
Definition: ojph_file.cpp:110
void close() override
Definition: ojph_file.cpp:134
void write_to_file(const char *file_name) const
Call this function to write the memory file data to a file.
Definition: ojph_file.cpp:186
int ojph_fseek(FILE *stream, si64 offset, int origin)
Definition: ojph_file.h:61
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
#define ojph_max(a, b)
Definition: ojph_defs.h:73
#define ojph_min(a, b)
Definition: ojph_defs.h:76
#define OJPH_ERROR(t,...)
Definition: ojph_message.h:287