Loading...
Searching...
No Matches
ojph_file.cpp
Go to the documentation of this file.
//***************************************************************************/
// This software is released under the 2-Clause BSD license, included
// below.
//
// Copyright (c) 2019, Aous Naman
// Copyright (c) 2019, Kakadu Software Pty Ltd, Australia
// Copyright (c) 2019, The University of New South Wales, Australia
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//***************************************************************************/
// This file is part of the OpenJPH software implementation.
// File: ojph_file.cpp
// Author: Aous Naman
// Date: 28 August 2019
//***************************************************************************/
#include <cassert>
#include <cstddef>
#include "ojph_mem.h"
#include "ojph_file.h"
#include "ojph_message.h"
namespace ojph {
//
//
//
//
//
void j2c_outfile::open(const char *filename)
{
assert(fh == 0);
fh = fopen(filename, "wb");
if (fh == NULL)
OJPH_ERROR(0x00060001, "failed to open %s for writing", filename);
}
size_t j2c_outfile::write(const void *ptr, size_t size)
{
assert(fh);
return fwrite(ptr, 1, size, fh);
}
si64 j2c_outfile::tell()
{
assert(fh);
return ojph_ftell(fh);
}
void j2c_outfile::flush()
{
assert(fh);
fflush(fh);
}
void j2c_outfile::close()
{
assert(fh);
fclose(fh);
fh = NULL;
}
//*************************************************************************/
// mem_outfile
//*************************************************************************/
mem_outfile::mem_outfile()
{
is_open = clear_mem = false;
buf_size = used_size = 0;
buf = cur_ptr = NULL;
}
mem_outfile::~mem_outfile()
{
if (buf)
ojph_aligned_free(buf);
is_open = clear_mem = false;
buf_size = used_size = 0;
buf = cur_ptr = NULL;
}
void mem_outfile::open(size_t initial_size, bool clear_mem)
{
assert(this->is_open == false);
assert(this->cur_ptr == this->buf);
// do initial buffer allocation or buffer expansion
this->is_open = true;
this->clear_mem = clear_mem;
expand_storage(initial_size, this->clear_mem);
this->used_size = 0;
this->cur_ptr = this->buf;
}
void mem_outfile::close() {
is_open = false;
cur_ptr = buf;
}
int mem_outfile::seek(si64 offset, enum outfile_base::seek origin)
{
if (origin == OJPH_SEEK_SET)
; // do nothing
else if (origin == OJPH_SEEK_CUR)
offset += tell();
else if (origin == OJPH_SEEK_END)
offset += (si64)used_size;
else {
assert(0);
return -1;
}
if (offset < 0) // offset before the start of file
return -1;
expand_storage((size_t)offset, false); // See if expansion is needed
cur_ptr = buf + offset;
return 0;
}
size_t mem_outfile::write(const void *ptr, size_t new_size)
{
assert(this->is_open);
assert(this->buf_size);
assert(this->buf);
assert(this->cur_ptr);
// expand buffer if needed to make sure it has room for this write
size_t needed_size = (size_t)tell() + new_size; //needed size
expand_storage(needed_size, false);
// copy bytes into buffer and adjust cur_ptr
memcpy(this->cur_ptr, ptr, new_size);
cur_ptr += new_size;
used_size = ojph_max(used_size, (size_t)tell());
return new_size;
}
void mem_outfile::write_to_file(const char *file_name) const
{
assert(is_open == false);
FILE *f = fopen(file_name, "wb");
if (f == NULL)
OJPH_ERROR(0x00060003, "failed to open %s for writing", file_name);
if (f != NULL)
if (fwrite(this->buf, 1, used_size, f) != used_size)
OJPH_ERROR(0x00060004, "failed writing to %s", file_name);
fclose(f);
}
void mem_outfile::expand_storage(size_t needed_size, bool clear_all)
{
if (needed_size > buf_size)
{
needed_size += (needed_size + 1) >> 1; // x1.5
// expand buffer to multiples of (ALIGNED_ALLOC_MASK + 1)
needed_size = (needed_size + ALIGNED_ALLOC_MASK) & (~ALIGNED_ALLOC_MASK);
ui8* new_buf;
new_buf = (ui8*)ojph_aligned_malloc(ALIGNED_ALLOC_MASK + 1, needed_size);
if (new_buf == NULL)
OJPH_ERROR(0x00060005, "failed to allocate memory (%zu bytes)",
needed_size);
if (this->buf != NULL)
{
if (!clear_all)
memcpy(new_buf, this->buf, used_size);
ojph_aligned_free(this->buf);
}
this->cur_ptr = new_buf + tell();
this->buf = new_buf;
if (clear_mem && !clear_all) // will be cleared later
memset(this->buf + buf_size, 0, needed_size - this->buf_size);
this->buf_size = needed_size;
}
if (clear_all)
memset(this->buf, 0, this->buf_size);
}
//
//
//
//
//
void j2c_infile::open(const char *filename)
{
assert(fh == NULL);
fh = fopen(filename, "rb");
if (fh == NULL)
OJPH_ERROR(0x00060002, "failed to open %s for reading", filename);
}
size_t j2c_infile::read(void *ptr, size_t size)
{
assert(fh);
return fread(ptr, 1, size, fh);
}
int j2c_infile::seek(si64 offset, enum infile_base::seek origin)
{
assert(fh);
return ojph_fseek(fh, offset, origin);
}
si64 j2c_infile::tell()
{
assert(fh);
return ojph_ftell(fh);
}
void j2c_infile::close()
{
assert(fh);
fclose(fh);
fh = NULL;
}
//
//
//
//
//
void mem_infile::open(const ui8* data, size_t size)
{
assert(this->data == NULL);
cur_ptr = this->data = data;
this->size = size;
}
size_t mem_infile::read(void *ptr, size_t size)
{
std::ptrdiff_t bytes_left = (data + this->size) - cur_ptr;
if (bytes_left > 0)
{
size_t bytes_to_read = ojph_min(size, (size_t)bytes_left);
memcpy(ptr, cur_ptr, bytes_to_read);
cur_ptr += bytes_to_read;
return bytes_to_read;
}
else
return 0;
}
int mem_infile::seek(si64 offset, enum infile_base::seek origin)
{
int result = -1;
if (origin == OJPH_SEEK_SET)
{
if (offset >= 0 && (size_t)offset <= size)
{
cur_ptr = data + offset;
result = 0;
}
}
else if (origin == OJPH_SEEK_CUR)
{
si64 bytes_off = (si64)(cur_ptr - data) + offset;
if (bytes_off >= 0 && (size_t)bytes_off <= size)
{
cur_ptr = data + bytes_off;
result = 0;
}
}
else if (origin == OJPH_SEEK_END)
{
if (offset <= 0 && (std::ptrdiff_t)size + offset >= 0)
{
cur_ptr = data + size + offset;
result = 0;
}
}
else
assert(0);
return result;
}
}
ojph::infile_base::seek
seek
Definition ojph_file.h:249
ojph::infile_base::OJPH_SEEK_END
@ OJPH_SEEK_END
Definition ojph_file.h:252
ojph::infile_base::OJPH_SEEK_SET
@ OJPH_SEEK_SET
Definition ojph_file.h:250
ojph::infile_base::OJPH_SEEK_CUR
@ OJPH_SEEK_CUR
Definition ojph_file.h:251
ojph::j2c_infile::close
void close() override
Definition ojph_file.cpp:271
ojph::j2c_infile::open
void open(const char *filename)
Definition ojph_file.cpp:241
ojph::j2c_infile::read
size_t read(void *ptr, size_t size) override
Definition ojph_file.cpp:250
ojph::j2c_infile::fh
FILE * fh
Definition ojph_file.h:284
ojph::j2c_infile::tell
si64 tell() override
Definition ojph_file.cpp:264
ojph::j2c_outfile::fh
FILE * fh
Definition ojph_file.h:110
ojph::j2c_outfile::flush
void flush() override
Definition ojph_file.cpp:84
ojph::j2c_outfile::close
void close() override
Definition ojph_file.cpp:91
ojph::j2c_outfile::tell
si64 tell() override
Definition ojph_file.cpp:77
ojph::j2c_outfile::open
void open(const char *filename)
Definition ojph_file.cpp:61
ojph::j2c_outfile::write
size_t write(const void *ptr, size_t size) override
Definition ojph_file.cpp:70
ojph::mem_infile::cur_ptr
const ui8 * cur_ptr
Definition ojph_file.h:305
ojph::mem_infile::read
size_t read(void *ptr, size_t size) override
Definition ojph_file.cpp:296
ojph::mem_infile::size
size_t size
Definition ojph_file.h:306
ojph::mem_infile::open
void open(const ui8 *data, size_t size)
Definition ojph_file.cpp:288
ojph::mem_infile::data
const ui8 * data
Definition ojph_file.h:305
ojph::mem_outfile::mem_outfile
mem_outfile()
Definition ojph_file.cpp:103
ojph::mem_outfile::used_size
size_t used_size
Definition ojph_file.h:237
ojph::mem_outfile::buf
ui8 * buf
Definition ojph_file.h:238
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:163
ojph::mem_outfile::ALIGNED_ALLOC_MASK
static const size_t ALIGNED_ALLOC_MASK
Definition ojph_file.h:242
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:167
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:200
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:121
ojph::mem_outfile::~mem_outfile
~mem_outfile() override
Definition ojph_file.cpp:111
ojph::mem_outfile::is_open
bool is_open
Definition ojph_file.h:234
ojph::mem_outfile::buf_size
size_t buf_size
Definition ojph_file.h:236
ojph::mem_outfile::cur_ptr
ui8 * cur_ptr
Definition ojph_file.h:239
ojph::mem_outfile::close
void close() override
Definition ojph_file.cpp:135
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:187
ojph::mem_outfile::clear_mem
bool clear_mem
Definition ojph_file.h:235
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