OpenJPH
Open-source implementation of JPEG2000 Part-15
Toggle main menu visibility
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
#include <utility>
46
47
#include "
ojph_mem.h
"
48
#include "
ojph_file.h
"
49
#include "
ojph_message.h
"
50
51
namespace
ojph
{
52
54
//
55
//
56
//
57
//
58
//
60
62
void
j2c_outfile::open
(
const
char
*filename)
63
{
64
assert(
fh
== 0);
65
fh
= fopen(filename,
"wb"
);
66
if
(
fh
== NULL)
67
OJPH_ERROR
(0x00060001,
"failed to open %s for writing"
, filename);
68
}
69
71
size_t
j2c_outfile::write
(
const
void
*ptr,
size_t
size
)
72
{
73
assert(
fh
);
74
return
fwrite(ptr, 1,
size
,
fh
);
75
}
76
78
si64
j2c_outfile::tell
()
79
{
80
assert(
fh
);
81
return
ojph_ftell
(
fh
);
82
}
83
85
void
j2c_outfile::flush
()
86
{
87
assert(
fh
);
88
fflush(
fh
);
89
}
90
92
void
j2c_outfile::close
()
93
{
94
assert(
fh
);
95
fclose(
fh
);
96
fh
= NULL;
97
}
98
100
//
101
//
102
// mem_outfile
103
//
104
//
106
108
mem_outfile::mem_outfile
()
109
{
110
is_open
=
clear_mem
=
false
;
111
buf_size
=
used_size
= 0;
112
buf
=
cur_ptr
=
nullptr
;
113
}
114
116
void
mem_outfile::swap
(
mem_outfile
& other)
noexcept
{
117
std::swap(this->
is_open
,other.is_open);
118
std::swap(this->
clear_mem
,other.clear_mem);
119
std::swap(this->
buf_size
,other.buf_size);
120
std::swap(this->
used_size
,other.used_size);
121
std::swap(this->
buf
,other.buf);
122
std::swap(this->
cur_ptr
,other.cur_ptr);
123
}
124
126
mem_outfile::~mem_outfile
()
127
{
128
if
(
buf
)
129
ojph_aligned_free
(
buf
);
130
is_open
=
clear_mem
=
false
;
131
buf_size
=
used_size
= 0;
132
buf
=
cur_ptr
= NULL;
133
}
134
136
mem_outfile::mem_outfile
(
mem_outfile
&& rhs)
noexcept
:
mem_outfile
()
137
{
138
this->
swap
(rhs);
139
}
140
142
mem_outfile
&
mem_outfile::operator=
(
mem_outfile
&& rhs)
noexcept
143
{
144
if
(
this
!= &rhs) {
145
mem_outfile
tmp(std::move(rhs));
146
this->
swap
(tmp);
147
}
148
return
*
this
;
149
}
150
152
void
mem_outfile::open
(
size_t
initial_size,
bool
clear_mem
)
153
{
154
assert(this->
is_open
==
false
);
155
assert(this->
cur_ptr
== this->
buf
);
156
157
// do initial buffer allocation or buffer expansion
158
this->
is_open
=
true
;
159
this->clear_mem =
clear_mem
;
160
expand_storage
(initial_size, this->clear_mem);
161
this->
used_size
= 0;
162
this->
cur_ptr
= this->
buf
;
163
}
164
166
void
mem_outfile::close
() {
167
is_open
=
false
;
168
cur_ptr
=
buf
;
169
}
170
172
175
int
mem_outfile::seek
(
si64
offset,
enum
outfile_base::seek
origin)
176
{
177
if
(origin ==
OJPH_SEEK_SET
)
178
;
// do nothing
179
else
if
(origin ==
OJPH_SEEK_CUR
)
180
offset +=
tell
();
181
else
if
(origin ==
OJPH_SEEK_END
)
182
offset += (
si64
)
used_size
;
183
else
{
184
assert(0);
185
return
-1;
186
}
187
188
if
(offset < 0)
// offset before the start of file
189
return
-1;
190
191
expand_storage
((
size_t
)offset,
false
);
// See if expansion is needed
192
193
cur_ptr
=
buf
+ offset;
194
return
0;
195
}
196
198
200
size_t
mem_outfile::write
(
const
void
*ptr,
size_t
new_size)
201
{
202
assert(this->
is_open
);
203
assert(this->
buf_size
);
204
assert(this->
buf
);
205
assert(this->
cur_ptr
);
206
207
// expand buffer if needed to make sure it has room for this write
208
size_t
needed_size = (size_t)
tell
() + new_size;
//needed size
209
expand_storage
(needed_size,
false
);
210
211
// copy bytes into buffer and adjust cur_ptr
212
memcpy(this->
cur_ptr
, ptr, new_size);
213
cur_ptr
+= new_size;
214
used_size
=
ojph_max
(
used_size
, (
size_t
)
tell
());
215
216
return
new_size;
217
}
218
220
void
mem_outfile::write_to_file
(
const
char
*file_name)
const
221
{
222
assert(
is_open
==
false
);
223
FILE *f = fopen(file_name,
"wb"
);
224
if
(f == NULL)
225
OJPH_ERROR
(0x00060003,
"failed to open %s for writing"
, file_name);
226
if
(f != NULL)
227
if
(fwrite(this->
buf
, 1,
used_size
, f) !=
used_size
)
228
OJPH_ERROR
(0x00060004,
"failed writing to %s"
, file_name);
229
fclose(f);
230
}
231
233
void
mem_outfile::expand_storage
(
size_t
needed_size,
bool
clear_all)
234
{
235
if
(needed_size >
buf_size
)
236
{
237
needed_size += (needed_size + 1) >> 1;
// x1.5
238
// expand buffer to multiples of (ALIGNED_ALLOC_MASK + 1)
239
needed_size = (needed_size +
ALIGNED_ALLOC_MASK
) & (~
ALIGNED_ALLOC_MASK
);
240
241
ui8
* new_buf;
242
new_buf = (
ui8
*)
ojph_aligned_malloc
(
ALIGNED_ALLOC_MASK
+ 1, needed_size);
243
if
(new_buf == NULL)
244
OJPH_ERROR
(0x00060005,
"failed to allocate memory (%zu bytes)"
,
245
needed_size);
246
247
if
(this->
buf
!= NULL)
248
{
249
if
(!clear_all)
250
memcpy(new_buf, this->
buf
,
used_size
);
251
ojph_aligned_free
(this->
buf
);
252
}
253
this->
cur_ptr
= new_buf +
tell
();
254
this->
buf
= new_buf;
255
256
if
(
clear_mem
&& !clear_all)
// will be cleared later
257
memset(this->
buf
+
buf_size
, 0, needed_size - this->
buf_size
);
258
this->
buf_size
= needed_size;
259
}
260
if
(clear_all)
261
memset(this->
buf
, 0, this->
buf_size
);
262
}
263
264
266
//
267
//
268
//
269
//
270
//
272
274
void
j2c_infile::open
(
const
char
*filename)
275
{
276
assert(
fh
== NULL);
277
fh
= fopen(filename,
"rb"
);
278
if
(
fh
== NULL)
279
OJPH_ERROR
(0x00060002,
"failed to open %s for reading"
, filename);
280
}
281
283
size_t
j2c_infile::read
(
void
*ptr,
size_t
size
)
284
{
285
assert(
fh
);
286
return
fread(ptr, 1,
size
,
fh
);
287
}
288
290
int
j2c_infile::seek
(
si64
offset,
enum
infile_base::seek
origin)
291
{
292
assert(
fh
);
293
return
ojph_fseek
(
fh
, offset, origin);
294
}
295
297
si64
j2c_infile::tell
()
298
{
299
assert(
fh
);
300
return
ojph_ftell
(
fh
);
301
}
302
304
void
j2c_infile::close
()
305
{
306
assert(
fh
);
307
fclose(
fh
);
308
fh
= NULL;
309
}
310
311
313
//
314
//
315
//
316
//
317
//
319
321
mem_infile::mem_infile
(
mem_infile
&& rhs)
noexcept
:
mem_infile
()
322
{
323
this->
swap
(rhs);
324
}
325
327
mem_infile
&
mem_infile::operator=
(
mem_infile
&& rhs)
noexcept
328
{
329
if
(
this
!= &rhs) {
330
mem_infile
tmp(std::move(rhs));
331
this->
swap
(tmp);
332
}
333
return
*
this
;
334
}
335
337
void
mem_infile::open
(
const
ui8
*
data
,
size_t
size
)
338
{
339
assert(this->data == NULL);
340
cur_ptr
= this->data =
data
;
341
this->size =
size
;
342
}
343
345
size_t
mem_infile::read
(
void
*ptr,
size_t
size
)
346
{
347
std::ptrdiff_t bytes_left = (
data
+ this->size) -
cur_ptr
;
348
if
(bytes_left > 0)
349
{
350
size_t
bytes_to_read =
ojph_min
(
size
, (
size_t
)bytes_left);
351
memcpy(ptr,
cur_ptr
, bytes_to_read);
352
cur_ptr
+= bytes_to_read;
353
return
bytes_to_read;
354
}
355
else
356
return
0;
357
}
358
360
int
mem_infile::seek
(
si64
offset,
enum
infile_base::seek
origin)
361
{
362
int
result = -1;
363
if
(origin ==
OJPH_SEEK_SET
)
364
{
365
if
(offset >= 0 && (
size_t
)offset <=
size
)
366
{
367
cur_ptr
=
data
+ offset;
368
result = 0;
369
}
370
}
371
else
if
(origin ==
OJPH_SEEK_CUR
)
372
{
373
si64
bytes_off = (
si64
)(
cur_ptr
-
data
) + offset;
374
if
(bytes_off >= 0 && (
size_t
)bytes_off <=
size
)
375
{
376
cur_ptr
=
data
+ bytes_off;
377
result = 0;
378
}
379
}
380
else
if
(origin ==
OJPH_SEEK_END
)
381
{
382
if
(offset <= 0 && (std::ptrdiff_t)
size
+ offset >= 0)
383
{
384
cur_ptr
=
data
+
size
+ offset;
385
result = 0;
386
}
387
}
388
else
389
assert(0);
390
391
return
result;
392
}
393
395
void
mem_infile::swap
(
mem_infile
& other)
noexcept
396
{
397
std::swap(this->
data
,other.data);
398
std::swap(this->
cur_ptr
,other.cur_ptr);
399
std::swap(this->
size
,other.size);
400
}
401
402
}
ojph::infile_base::seek
seek
Definition
ojph_file.h:269
ojph::infile_base::OJPH_SEEK_END
@ OJPH_SEEK_END
Definition
ojph_file.h:272
ojph::infile_base::OJPH_SEEK_SET
@ OJPH_SEEK_SET
Definition
ojph_file.h:270
ojph::infile_base::OJPH_SEEK_CUR
@ OJPH_SEEK_CUR
Definition
ojph_file.h:271
ojph::j2c_infile::close
void close() override
Definition
ojph_file.cpp:304
ojph::j2c_infile::open
void open(const char *filename)
Definition
ojph_file.cpp:274
ojph::j2c_infile::read
size_t read(void *ptr, size_t size) override
Definition
ojph_file.cpp:283
ojph::j2c_infile::fh
FILE * fh
Definition
ojph_file.h:304
ojph::j2c_infile::tell
si64 tell() override
Definition
ojph_file.cpp:297
ojph::j2c_outfile::fh
FILE * fh
Definition
ojph_file.h:110
ojph::j2c_outfile::flush
void flush() override
Definition
ojph_file.cpp:85
ojph::j2c_outfile::close
void close() override
Definition
ojph_file.cpp:92
ojph::j2c_outfile::tell
si64 tell() override
Definition
ojph_file.cpp:78
ojph::j2c_outfile::open
void open(const char *filename)
Definition
ojph_file.cpp:62
ojph::j2c_outfile::write
size_t write(const void *ptr, size_t size) override
Definition
ojph_file.cpp:71
ojph::mem_infile::mem_infile
mem_infile()
Definition
ojph_file.h:311
ojph::mem_infile::cur_ptr
const ui8 * cur_ptr
Definition
ojph_file.h:342
ojph::mem_infile::read
size_t read(void *ptr, size_t size) override
Definition
ojph_file.cpp:345
ojph::mem_infile::mem_infile
mem_infile(mem_infile &&) noexcept
Definition
ojph_file.cpp:321
ojph::mem_infile::size
size_t size
Definition
ojph_file.h:343
ojph::mem_infile::open
void open(const ui8 *data, size_t size)
Definition
ojph_file.cpp:337
ojph::mem_infile::swap
void swap(mem_infile &) noexcept
Definition
ojph_file.cpp:395
ojph::mem_infile::operator=
mem_infile & operator=(mem_infile const &)=delete
ojph::mem_infile::data
const ui8 * data
Definition
ojph_file.h:342
ojph::mem_outfile::mem_outfile
mem_outfile()
Definition
ojph_file.cpp:108
ojph::mem_outfile::used_size
size_t used_size
Definition
ojph_file.h:257
ojph::mem_outfile::buf
ui8 * buf
Definition
ojph_file.h:258
ojph::mem_outfile::tell
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:177
ojph::mem_outfile::ALIGNED_ALLOC_MASK
static const size_t ALIGNED_ALLOC_MASK
Definition
ojph_file.h:262
ojph::mem_outfile::write
size_t write(const void *ptr, size_t size) override
Call this function to write data to the memory file.
Definition
ojph_file.cpp:200
ojph::mem_outfile::expand_storage
void expand_storage(size_t new_size, bool clear_all)
This function expands storage by x1.5 needed space.
Definition
ojph_file.cpp:233
ojph::mem_outfile::open
void open(size_t initial_size=65536, bool clear_mem=false)
Call this function to open a memory file.
Definition
ojph_file.cpp:152
ojph::mem_outfile::~mem_outfile
~mem_outfile() override
Definition
ojph_file.cpp:126
ojph::mem_outfile::is_open
bool is_open
Definition
ojph_file.h:254
ojph::mem_outfile::operator=
mem_outfile & operator=(mem_outfile const &)=delete
ojph::mem_outfile::swap
void swap(mem_outfile &other) noexcept
A utility function to swap the contents of two instances.
Definition
ojph_file.cpp:116
ojph::mem_outfile::buf_size
size_t buf_size
Definition
ojph_file.h:256
ojph::mem_outfile::cur_ptr
ui8 * cur_ptr
Definition
ojph_file.h:259
ojph::mem_outfile::close
void close() override
Definition
ojph_file.cpp:166
ojph::mem_outfile::write_to_file
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:220
ojph::mem_outfile::clear_mem
bool clear_mem
Definition
ojph_file.h:255
ojph::outfile_base::seek
seek
Definition
ojph_file.h:78
ojph::outfile_base::OJPH_SEEK_CUR
@ OJPH_SEEK_CUR
Definition
ojph_file.h:80
ojph::outfile_base::OJPH_SEEK_END
@ OJPH_SEEK_END
Definition
ojph_file.h:81
ojph::outfile_base::OJPH_SEEK_SET
@ OJPH_SEEK_SET
Definition
ojph_file.h:79
ojph
Definition
ojph_img_io.h:52
ojph::ojph_fseek
int ojph_fseek(FILE *stream, si64 offset, int origin)
Definition
ojph_file.h:61
ojph::ojph_aligned_malloc
void * ojph_aligned_malloc(size_t alignment, size_t size)
ojph::ojph_ftell
si64 ojph_ftell(FILE *stream)
Definition
ojph_file.h:66
ojph::si64
int64_t si64
Definition
ojph_defs.h:57
ojph::ui8
uint8_t ui8
Definition
ojph_defs.h:50
ojph::ojph_aligned_free
void ojph_aligned_free(void *pointer)
ojph_max
#define ojph_max(a, b)
Definition
ojph_defs.h:73
ojph_min
#define ojph_min(a, b)
Definition
ojph_defs.h:76
ojph_file.h
ojph_mem.h
ojph_message.h
OJPH_ERROR
#define OJPH_ERROR(t,...)
Definition
ojph_message.h:288
ojph::size
Definition
ojph_base.h:48
src
core
others
ojph_file.cpp
Generated by
1.18.0