Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions cmd/bitmaphook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

/// Includes
#include "cmd/bitmaphook.hpp"
#include "cmd/iohelpers.hpp"
#include "std/stdio.hpp"
#include "std/stdlib.hpp"
#include "std/string.hpp"
Expand Down Expand Up @@ -281,20 +280,27 @@ JPG_LONG BitmapHook(struct JPG_Hook *hook, struct JPG_TagItem *tags)
switch(bmm->bmm_usDepth) {
case 1:
case 3: // The direct cases, can write PPM right away.
#ifdef JPG_LIL_ENDIAN

// On those bloddy little endian machines, an endian swap is necessary
// as PNM is big-endian.
if (bmm->bmm_ucPixelType == CTYP_UWORD) {
bool turnBytePairs = bmm->bmm_ucPixelType == CTYP_UWORD;
#ifdef JPG_LIL_ENDIAN
turnBytePairs &= bmm->bmm_decodedFormat == PPM;
#else
turnBytePairs &= bmm->bmm_decodedFormat == RAW;
#endif
if (turnBytePairs) {
ULONG count = bmm->bmm_ulWidth * height * bmm->bmm_usDepth;
UWORD *data = (UWORD *)bmm->bmm_pMemPtr;
do {
*data = (*data >> 8) | ((*data & 0xff) << 8);
data++;
} while(--count);
}
#endif
fwrite(bmm->bmm_pMemPtr,bmm->bmm_ucPixelType & CTYP_SIZE_MASK,
bmm->bmm_ulWidth * height * bmm->bmm_usDepth,bmm->bmm_pTarget);

const size_t dataSize =
(bmm->bmm_ucPixelType & CTYP_SIZE_MASK) * bmm->bmm_ulWidth * height * bmm->bmm_usDepth;
bmm->bmm_pTarget->write(bmm->bmm_pMemPtr, dataSize);
break;
}
}
Expand Down Expand Up @@ -455,8 +461,10 @@ JPG_LONG AlphaHook(struct JPG_Hook *hook, struct JPG_TagItem *tags)
} while(--count);
}
#endif
fwrite(bmm->bmm_pAlphaPtr,bmm->bmm_ucAlphaType & CTYP_SIZE_MASK,
bmm->bmm_ulWidth * height,bmm->bmm_pAlphaTarget);
const size_t dataSize = (bmm->bmm_ucAlphaType & CTYP_SIZE_MASK) * bmm->bmm_ulWidth * height;
bmm->bmm_pAlphaTarget->write(bmm->bmm_pMemPtr, dataSize);
//fwrite(bmm->bmm_pAlphaPtr,bmm->bmm_ucAlphaType & CTYP_SIZE_MASK,
// bmm->bmm_ulWidth * height,bmm->bmm_pAlphaTarget);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions cmd/bitmaphook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
/// Includes
#include "interface/types.hpp"
#include "std/stdio.hpp"
#include "cmd/iohelpers.hpp"
///

/// Forwards
Expand All @@ -54,10 +55,10 @@ struct BitmapMemory {
UWORD bmm_usDepth; // number of components.
UBYTE bmm_ucPixelType; // precision etc.
UBYTE bmm_ucAlphaType; // pixel type of the alpha channel
FILE *bmm_pTarget; // where to write the data to.
HookDataAccessor *bmm_pTarget; // where to write the data to.
FILE *bmm_pSource; // where the data comes from on reading (encoding)
FILE *bmm_pLDRSource; // if there is a separate source for the LDR image, this is non-NULL.
FILE *bmm_pAlphaTarget;// where the alpha (if any) goes to on decoding
HookDataAccessor *bmm_pAlphaTarget;// where the alpha (if any) goes to on decoding
FILE *bmm_pAlphaSource;// where the alpha data (if any) comes from. There is no dedicated alpha LDR file
const UWORD *bmm_HDR2LDR; // the (simple global) tone mapper used for encoding the image.
bool bmm_bFloat; // is true if the input is floating point
Expand All @@ -68,6 +69,7 @@ struct BitmapMemory {
bool bmm_bNoAlphaOutputConversion; // ditto for alpha
bool bmm_bClamp; // if set, clamp negative values to zero.
bool bmm_bAlphaClamp; // if set, alpha values outside [0,1] will be clamped to range
DecodedFormat bmm_decodedFormat; // decoded format(ppm or raw)
};
///

Expand Down
3 changes: 2 additions & 1 deletion cmd/encodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ void EncodeC(const char *source,const char *ldrsource,const char *target,const c
}
//
FILE *out = fopen(target,"wb");
FileHookDataAccessor outFileDataAccessor(out);
if (out) {
int frametype = JPGFLAG_SEQUENTIAL;
int residualtype = JPGFLAG_RESIDUAL;
Expand Down Expand Up @@ -643,7 +644,7 @@ void EncodeC(const char *source,const char *ldrsource,const char *target,const c
ok = jpeg->ProvideImage(tags);

if (ok) {
struct JPG_Hook filehook(FileHook,out);
struct JPG_Hook filehook(FileHook, &outFileDataAccessor);
struct JPG_TagItem iotags[] = {
JPG_PointerTag(JPGTAG_HOOK_IOHOOK,&filehook),
JPG_PointerTag(JPGTAG_HOOK_IOSTREAM,out),
Expand Down
80 changes: 71 additions & 9 deletions cmd/filehook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,90 @@
#include "interface/hooks.hpp"
#include "interface/tagitem.hpp"
#include "interface/parameters.hpp"
#include "std/stdio.hpp"
#include "std/assert.hpp"
#include <algorithm>
///

HookDataAccessor::~HookDataAccessor()
{
}

FileHookDataAccessor::FileHookDataAccessor(FILE *file): m_file(file)
{
}

JPG_LONG FileHookDataAccessor::write(JPG_CPTR data, JPG_LONG size)
{
return fwrite(data, 1, size, m_file);
}

JPG_LONG FileHookDataAccessor::read(JPG_APTR destination, JPG_LONG size)
{
return fread(destination, 1, size, m_file);
}

JPG_LONG FileHookDataAccessor::seek(JPG_LONG offset, JPG_LONG origin)
{
return fseek(m_file, offset, origin);
}

UserDataHookAccessor::UserDataHookAccessor(JPG_APTR data, JPG_LONG dataSize):
m_data(reinterpret_cast<UBYTE*>(data)), m_dataSize(dataSize), m_curPosition(0)
{
}

JPG_LONG UserDataHookAccessor::read(JPG_APTR destination, JPG_LONG size)
{
const JPG_LONG bytesNumberToCopy = std::min(size, m_dataSize - m_curPosition);
memcpy(destination, m_data + m_curPosition, bytesNumberToCopy);
m_curPosition += bytesNumberToCopy;
return bytesNumberToCopy;
}

JPG_LONG UserDataHookAccessor::write(JPG_CPTR data, JPG_LONG size)
{
const JPG_LONG bytesNumberToCopy = std::min(size, m_dataSize - m_curPosition);
memcpy(m_data + m_curPosition, data, bytesNumberToCopy);
m_curPosition += bytesNumberToCopy;
return bytesNumberToCopy;
}

JPG_LONG UserDataHookAccessor::seek(JPG_LONG offset, JPG_LONG origin)
{
switch(origin) {
case SEEK_CUR:
m_curPosition += offset;
break;
case SEEK_SET:
m_curPosition = offset;
break;
case SEEK_END:
m_curPosition = m_dataSize - offset;
break;
}

return 0;
}

/// The IO hook function
JPG_LONG FileHook(struct JPG_Hook *hook, struct JPG_TagItem *tags)
{
FILE *in = (FILE *)(hook->hk_pData);
HookDataAccessor *in = (HookDataAccessor *)(hook->hk_pData);

switch(tags->GetTagData(JPGTAG_FIO_ACTION)) {
case JPGFLAG_ACTION_READ:
{
UBYTE *buffer = (UBYTE *)tags->GetTagPtr(JPGTAG_FIO_BUFFER);
ULONG size = (ULONG )tags->GetTagData(JPGTAG_FIO_SIZE);
return fread(buffer,1,size,in);

return in->read(buffer, size);
}
case JPGFLAG_ACTION_WRITE:
{
UBYTE *buffer = (UBYTE *)tags->GetTagPtr(JPGTAG_FIO_BUFFER);
ULONG size = (ULONG )tags->GetTagData(JPGTAG_FIO_SIZE);
return fwrite(buffer,1,size,in);

return in->write(buffer, size);
}
case JPGFLAG_ACTION_SEEK:
{
Expand All @@ -67,11 +129,11 @@ JPG_LONG FileHook(struct JPG_Hook *hook, struct JPG_TagItem *tags)

switch(mode) {
case JPGFLAG_OFFSET_CURRENT:
return fseek(in,offset,SEEK_CUR);
return in->seek(offset, SEEK_CUR);
case JPGFLAG_OFFSET_BEGINNING:
return fseek(in,offset,SEEK_SET);
return in->seek(offset, SEEK_SET);
case JPGFLAG_OFFSET_END:
return fseek(in,offset,SEEK_END);
return in->seek(offset, SEEK_END);
}
}
case JPGFLAG_ACTION_QUERY:
Expand Down
36 changes: 36 additions & 0 deletions cmd/filehook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,49 @@

/// Includes
#include "interface/types.hpp"
#include "std/stdio.hpp"
#include <cstring>
///

/// Forwards
struct JPG_Hook;
struct JPG_TagItem;
///

struct HookDataAccessor
{
virtual JPG_LONG read(JPG_APTR destination, JPG_LONG size) = 0;
virtual JPG_LONG write(JPG_CPTR data, JPG_LONG size) = 0;
virtual JPG_LONG seek(JPG_LONG offset, JPG_LONG origin) = 0;
virtual ~HookDataAccessor();
};

struct FileHookDataAccessor: public HookDataAccessor
{
FileHookDataAccessor(FILE *file);

virtual JPG_LONG read(JPG_APTR destination, JPG_LONG size);
virtual JPG_LONG write(JPG_CPTR data, JPG_LONG size);
virtual JPG_LONG seek(JPG_LONG offset, JPG_LONG origin);

private:
FILE *m_file;
};

struct UserDataHookAccessor: public HookDataAccessor
{
UserDataHookAccessor(JPG_APTR data, JPG_LONG dataSize);

virtual JPG_LONG read(JPG_APTR destination, JPG_LONG size);
virtual JPG_LONG write(JPG_CPTR data, JPG_LONG size);
virtual JPG_LONG seek(JPG_LONG offset, JPG_LONG origin);

private:
UBYTE* m_data;
JPG_LONG m_dataSize;
JPG_LONG m_curPosition;
};

/// Prototypes
extern JPG_LONG FileHook(struct JPG_Hook *hook, struct JPG_TagItem *tags);
///
Expand Down
22 changes: 12 additions & 10 deletions cmd/iohelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "interface/types.hpp"
#include "std/stdio.hpp"
#include "std/math.hpp"
#include "cmd/filehook.hpp"
///

/// Prototypes
Expand Down Expand Up @@ -133,26 +134,27 @@ double inline readFloat(FILE *in,bool bigendian)

/// writeFloat
// Write a floating point number to a file
void inline writeFloat(FILE *out,FLOAT f,bool bigendian)
void inline writeFloat(HookDataAccessor *out,FLOAT f,bool bigendian)
{
union {
LONG long_buf;
FLOAT float_buf;
} u;

u.float_buf = f;
UBYTE* data = reinterpret_cast<UBYTE*>(&u.long_buf);

if (bigendian) {
putc(u.long_buf >> 24,out);
putc(u.long_buf >> 16,out);
putc(u.long_buf >> 8,out);
putc(u.long_buf >> 0,out);
} else {
putc(u.long_buf >> 0,out);
putc(u.long_buf >> 8,out);
putc(u.long_buf >> 16,out);
putc(u.long_buf >> 24,out);
UBYTE byteForSwap = data[0];
data[0] = data[3];
data[3] = byteForSwap;

byteForSwap = data[1];
data[1] = data[2];
data[2] = byteForSwap;
}

out->write(data, 4);
}
///

Expand Down
8 changes: 7 additions & 1 deletion cmd/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ void PrintUsage(const char *progname)
"-N : enable noise shaping of the prediction residual\n"
"-l : enable lossless coding without a residual image by an\n"
" int-to-int DCT, also requires -c and -q 100 for true lossless\n"
"-raw : decoding to raw(not ppm)\n"
#if ACCUSOFT_CODE
"-p : JPEG lossless (predictive) mode\n"
" also requires -c for true lossless\n"
Expand Down Expand Up @@ -379,6 +380,7 @@ int main(int argc,char **argv)
bool noclamp = false;
bool setprofile = false;
bool median = true;
bool raw = false;
int splitquality = -1;
int profile = 2; // profile C.
const char *sub = NULL;
Expand Down Expand Up @@ -430,6 +432,10 @@ int main(int argc,char **argv)
median = true;
argv++;
argc--;
} else if (!strcmp(argv[1],"-raw")) {
raw = true;
argv++;
argc--;
} else if (!strcmp(argv[1],"-ct")) {
median = false;
argv++;
Expand Down Expand Up @@ -691,7 +697,7 @@ int main(int argc,char **argv)
}

if (quality < 0 && lossless == false && lsmode < 0) {
Reconstruct(argv[1],argv[2],colortrafo,alpha);
Reconstruct(argv[1], argv[2], (raw ? RAW : PPM), colortrafo, alpha);
} else {
switch(profile) {
case 0:
Expand Down
Loading