#include "../../internal/dcraw_defs.h"
ushort LibRaw::sget2Rev(uchar *s) {
if (order == 0x4d4d)
return s[0] | s[1] << 8;
else
return s[0] << 8 | s[1];
}
ushort LibRaw::get2()
{
uchar str[2] = {0xff, 0xff};
fread(str, 1, 2, ifp);
return sget2(str);
}
unsigned LibRaw::sget4(uchar *s)
{
if (order == 0x4949)
return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
else
return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
}
#define sget4(s) sget4((uchar *)s)
unsigned LibRaw::get4()
{
uchar str[4] = {0xff, 0xff, 0xff, 0xff};
fread(str, 1, 4, ifp);
return sget4(str);
}
unsigned LibRaw::getint(int type) { return tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) ? get2() : get4(); }
float LibRaw::int_to_float(int i)
{
union {
int i;
float f;
} u;
u.i = i;
return u.f;
}
double LibRaw::getreal(int type)
{
union {
char c[8];
double d;
} u, v;
int i, rev;
switch (type)
{
case LIBRAW_EXIFTAG_TYPE_SHORT:
return (unsigned short)get2();
case LIBRAW_EXIFTAG_TYPE_LONG:
return (unsigned int)get4();
case LIBRAW_EXIFTAG_TYPE_RATIONAL: u.d = (unsigned int)get4();
v.d = (unsigned int)get4();
return u.d / (v.d ? v.d : 1);
case LIBRAW_EXIFTAG_TYPE_SSHORT:
return (signed short)get2();
case LIBRAW_EXIFTAG_TYPE_SLONG:
return (signed int)get4();
case LIBRAW_EXIFTAG_TYPE_SRATIONAL: u.d = (signed int)get4();
v.d = (signed int)get4();
return u.d / (v.d ? v.d : 1);
case LIBRAW_EXIFTAG_TYPE_FLOAT:
return int_to_float(get4());
case LIBRAW_EXIFTAG_TYPE_DOUBLE:
rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
for (i = 0; i < 8; i++)
u.c[i ^ rev] = fgetc(ifp);
return u.d;
default:
return fgetc(ifp);
}
}
double LibRaw::sgetreal(int type, uchar *s)
{
union {
char c[8];
double d;
} u, v;
int i, rev;
switch (type)
{
case LIBRAW_EXIFTAG_TYPE_SHORT:
return (unsigned short)sget2(s);
case LIBRAW_EXIFTAG_TYPE_LONG:
return (unsigned int)sget4(s);
case LIBRAW_EXIFTAG_TYPE_RATIONAL: u.d = (unsigned int)sget4(s);
v.d = (unsigned int)sget4(s+4);
return u.d / (v.d ? v.d : 1);
case LIBRAW_EXIFTAG_TYPE_SSHORT:
return (signed short)sget2(s);
case LIBRAW_EXIFTAG_TYPE_SLONG:
return (signed int)sget4(s);
case LIBRAW_EXIFTAG_TYPE_SRATIONAL: u.d = (signed int)sget4(s);
v.d = (signed int)sget4(s+4);
return u.d / (v.d ? v.d : 1);
case LIBRAW_EXIFTAG_TYPE_FLOAT:
return int_to_float(sget4(s));
case LIBRAW_EXIFTAG_TYPE_DOUBLE:
rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
for (i = 0; i < 8; i++)
u.c[i ^ rev] = *(s+1);
return u.d;
default:
return *(s+1);
}
}
void LibRaw::read_shorts(ushort *pixel, unsigned count)
{
if ((unsigned)fread(pixel, 2, count, ifp) < count)
derror();
if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
swab((char *)pixel, (char *)pixel, count * 2);
}