commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
152
include/modules/pict_io_jpeglib/pict_jpeglib_codec.cpp
Normal file
152
include/modules/pict_io_jpeglib/pict_jpeglib_codec.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "pict_io_jpeglib/pict_jpeglib_codec.h"
|
||||
#include "picture/pict.h"
|
||||
#include "container/narray.h"
|
||||
|
||||
using namespace GS;
|
||||
|
||||
|
||||
#if 1
|
||||
|
||||
extern "C"
|
||||
{
|
||||
int JpgLoad_ansic(void *buf, int len, char **output, unsigned int *width, unsigned int *height);
|
||||
int JpgSave_ansic(char *dst, int dst_len, int *size, int qual, char *buf, unsigned int w, unsigned int h);
|
||||
void JpgFree_ansic(char **p);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void FetchHCoef(char *bf, int w, int /*h*/, int x, int y, float *cf)
|
||||
{
|
||||
bf += y * w * 3;
|
||||
for ( int p = (x - 2); p < (x + 2); p++ )
|
||||
{
|
||||
int op = p;
|
||||
if ( op < 0 ) op = 0;
|
||||
else if ( op >= w ) op = w - 1;
|
||||
*cf++ = (float)((unsigned char)bf[op * 3]);
|
||||
}
|
||||
}
|
||||
float Spline4Inter(float t, float *cf)
|
||||
{
|
||||
float v = cf[1]+0.5f*t*(cf[2]-cf[0]+t*(cf[2]+cf[1]*(-2.0f)+cf[0]+t*((cf[2]-cf[1])*9.0f+(cf[0]-cf[3])*3.f+t*((cf[1]-cf[2])*15.f+(cf[3]-cf[0])*5.f+t*((cf[2]-cf[1])*6.f+(cf[0]-cf[3])*2.f)))));
|
||||
if ( v < 0.f )
|
||||
v = 0.f;
|
||||
else if ( v > 255.f )
|
||||
v = 255.f;
|
||||
return v;
|
||||
}
|
||||
char *RgbResize(char *rgb, int ow, int oh, int w, int h)
|
||||
{
|
||||
char *nr = new char[w * h * 3], *pr;
|
||||
int x, y, c, v;
|
||||
float hc[4], vc[4];
|
||||
float px, py, dx, dy;
|
||||
|
||||
dx = (float)ow / (float)w;
|
||||
dy = (float)oh / (float)h;
|
||||
|
||||
py = 0.f;
|
||||
pr = nr;
|
||||
for ( y = 0; y < h; y++ )
|
||||
{
|
||||
px = 0.f;
|
||||
for ( x = 0; x < w; x++ )
|
||||
{
|
||||
for ( c = 0; c < 3; c++ )
|
||||
{
|
||||
float *pvc = vc;
|
||||
for ( v = -2; v < 2; v++ )
|
||||
{
|
||||
int sy = v + (int)py;
|
||||
if ( sy < 0 ) sy = 0;
|
||||
if ( sy >= oh ) sy = oh - 1;
|
||||
FetchHCoef(rgb + c, ow, oh, (int)px, sy, hc);
|
||||
*pvc++ = Spline4Inter(px - ((int)px), hc);
|
||||
}
|
||||
*pr++ = (unsigned char)Spline4Inter(py - ((int)py), vc);
|
||||
}
|
||||
px += dx;
|
||||
}
|
||||
py += dy;
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void JpeglibCppInterfaceFree(char **p)
|
||||
{ JpgFree_ansic(p); }
|
||||
int JpeglibCppInterfaceLoad(void *f, int l, char **o, unsigned int *w, unsigned int *h)
|
||||
{ return JpgLoad_ansic(f, l, o, w, h); }
|
||||
int JpeglibCppInterfaceSave(char *dst, int dst_len, int *size, int q, char *b, unsigned int w, unsigned int h)
|
||||
{ return JpgSave_ansic(dst, dst_len, size, q, b, w, h); }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool PictureJpeglibCodec::Load(IO::Handle &handle, Picture &picture)
|
||||
{
|
||||
uchar header[2];
|
||||
handle.Rewind();
|
||||
if (handle.Read(header, 2) != 2)
|
||||
return false;
|
||||
if ((header[0] != 0xff) || (header[1] != 0xd8))
|
||||
return false;
|
||||
|
||||
// SOI marker found, good to go.
|
||||
size_t size = handle.GetSize();
|
||||
Array <void *> buffer((uint)size);
|
||||
if (!buffer)
|
||||
return false;
|
||||
|
||||
handle.Rewind();
|
||||
handle.Read(buffer, size);
|
||||
|
||||
uint width, height;
|
||||
char *c_data = NULL;
|
||||
|
||||
if (JpeglibCppInterfaceLoad(buffer, (int)size, &c_data, &width, &height))
|
||||
{
|
||||
// Transfer C data to a C++ allocation.
|
||||
picture.AllocAs(width, height);
|
||||
if (uchar *data = picture.GetData())
|
||||
{
|
||||
uchar *j_data = (uchar *)c_data;
|
||||
for (uint h = 0; h < height; ++h)
|
||||
for (uint w = 0; w < width; ++w)
|
||||
{
|
||||
data[0] = j_data[2];
|
||||
data[1] = j_data[1];
|
||||
data[2] = j_data[0];
|
||||
data[3] = j_data[3];
|
||||
j_data += 4;
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Drop C data.
|
||||
JpeglibCppInterfaceFree(&c_data);
|
||||
}
|
||||
return asbool(picture.GetData());
|
||||
}
|
||||
bool PictureJpeglibCodec::Save(IO::Handle &handle, const Picture &picture)
|
||||
{
|
||||
// FIXME this is stupid.
|
||||
Array <char> dst(5000000);
|
||||
if (!dst)
|
||||
return false;
|
||||
|
||||
int size = 0;
|
||||
if (!JpeglibCppInterfaceSave(&dst[0], (uint)dst.GetSize(), &size, 100, (char *)picture.GetData(), picture.GetWidth(), picture.GetHeight()))
|
||||
return false;
|
||||
|
||||
return handle.Write(dst, size) == (size_t)size;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user