mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-24 08:14:10 +03:00
Format with ClangFormat
This commit is contained in:
parent
e2d00f8cf8
commit
46b7e86bab
|
@ -79,14 +79,16 @@ typedef struct Tcl_Interp Tcl_Interp;
|
||||||
typedef struct Tcl_Command_ *Tcl_Command;
|
typedef struct Tcl_Command_ *Tcl_Command;
|
||||||
typedef void *ClientData;
|
typedef void *ClientData;
|
||||||
|
|
||||||
typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp
|
typedef int(Tcl_CmdProc)(
|
||||||
*interp, int argc, const char *argv[]);
|
ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]);
|
||||||
typedef void(Tcl_CmdDeleteProc)(ClientData clientData);
|
typedef void(Tcl_CmdDeleteProc)(ClientData clientData);
|
||||||
|
|
||||||
/* Typedefs derived from function signatures in Tcl header */
|
/* Typedefs derived from function signatures in Tcl header */
|
||||||
/* Tcl_CreateCommand */
|
/* Tcl_CreateCommand */
|
||||||
typedef Tcl_Command (*Tcl_CreateCommand_t)(Tcl_Interp *interp,
|
typedef Tcl_Command (*Tcl_CreateCommand_t)(
|
||||||
const char *cmdName, Tcl_CmdProc *proc,
|
Tcl_Interp *interp,
|
||||||
|
const char *cmdName,
|
||||||
|
Tcl_CmdProc *proc,
|
||||||
ClientData clientData,
|
ClientData clientData,
|
||||||
Tcl_CmdDeleteProc *deleteProc);
|
Tcl_CmdDeleteProc *deleteProc);
|
||||||
/* Tcl_AppendResult */
|
/* Tcl_AppendResult */
|
||||||
|
@ -107,8 +109,7 @@ typedef struct Tk_Window_ *Tk_Window;
|
||||||
|
|
||||||
typedef void *Tk_PhotoHandle;
|
typedef void *Tk_PhotoHandle;
|
||||||
|
|
||||||
typedef struct Tk_PhotoImageBlock
|
typedef struct Tk_PhotoImageBlock {
|
||||||
{
|
|
||||||
unsigned char *pixelPtr;
|
unsigned char *pixelPtr;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
@ -119,23 +120,30 @@ typedef struct Tk_PhotoImageBlock
|
||||||
|
|
||||||
/* Typedefs derived from function signatures in Tk header */
|
/* Typedefs derived from function signatures in Tk header */
|
||||||
/* Tk_PhotoPutBlock for Tk <= 8.4 */
|
/* Tk_PhotoPutBlock for Tk <= 8.4 */
|
||||||
typedef void (*Tk_PhotoPutBlock_84_t) (Tk_PhotoHandle handle,
|
typedef void (*Tk_PhotoPutBlock_84_t)(
|
||||||
Tk_PhotoImageBlock *blockPtr, int x, int y,
|
|
||||||
int width, int height, int compRule);
|
|
||||||
/* Tk_PhotoPutBlock for Tk >= 8.5 */
|
|
||||||
typedef int (*Tk_PhotoPutBlock_85_t) (Tcl_Interp * interp,
|
|
||||||
Tk_PhotoHandle handle,
|
Tk_PhotoHandle handle,
|
||||||
Tk_PhotoImageBlock * blockPtr, int x, int y,
|
Tk_PhotoImageBlock *blockPtr,
|
||||||
int width, int height, int compRule);
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int compRule);
|
||||||
|
/* Tk_PhotoPutBlock for Tk >= 8.5 */
|
||||||
|
typedef int (*Tk_PhotoPutBlock_85_t)(
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
Tk_PhotoHandle handle,
|
||||||
|
Tk_PhotoImageBlock *blockPtr,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int compRule);
|
||||||
/* Tk_PhotoSetSize for Tk <= 8.4 */
|
/* Tk_PhotoSetSize for Tk <= 8.4 */
|
||||||
typedef void (*Tk_PhotoSetSize_84_t) (Tk_PhotoHandle handle,
|
typedef void (*Tk_PhotoSetSize_84_t)(Tk_PhotoHandle handle, int width, int height);
|
||||||
int width, int height);
|
|
||||||
/* Tk_FindPhoto */
|
/* Tk_FindPhoto */
|
||||||
typedef Tk_PhotoHandle (*Tk_FindPhoto_t) (Tcl_Interp *interp,
|
typedef Tk_PhotoHandle (*Tk_FindPhoto_t)(Tcl_Interp *interp, const char *imageName);
|
||||||
const char *imageName);
|
|
||||||
/* Tk_PhotoGetImage */
|
/* Tk_PhotoGetImage */
|
||||||
typedef int (*Tk_PhotoGetImage_t) (Tk_PhotoHandle handle,
|
typedef int (*Tk_PhotoGetImage_t)(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr);
|
||||||
Tk_PhotoImageBlock * blockPtr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* end block for C++
|
* end block for C++
|
||||||
|
|
|
@ -58,8 +58,7 @@ static Tk_PhotoSetSize_84_t TK_PHOTO_SET_SIZE_84;
|
||||||
static Tk_PhotoPutBlock_85_t TK_PHOTO_PUT_BLOCK_85;
|
static Tk_PhotoPutBlock_85_t TK_PHOTO_PUT_BLOCK_85;
|
||||||
|
|
||||||
static Imaging
|
static Imaging
|
||||||
ImagingFind(const char* name)
|
ImagingFind(const char *name) {
|
||||||
{
|
|
||||||
Py_ssize_t id;
|
Py_ssize_t id;
|
||||||
|
|
||||||
/* FIXME: use CObject instead? */
|
/* FIXME: use CObject instead? */
|
||||||
|
@ -75,27 +74,23 @@ ImagingFind(const char* name)
|
||||||
return (Imaging)id;
|
return (Imaging)id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp,
|
PyImagingPhotoPut(
|
||||||
int argc, const char **argv)
|
ClientData clientdata, Tcl_Interp *interp, int argc, const char **argv) {
|
||||||
{
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
Tk_PhotoHandle photo;
|
Tk_PhotoHandle photo;
|
||||||
Tk_PhotoImageBlock block;
|
Tk_PhotoImageBlock block;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
TCL_APPEND_RESULT(interp, "usage: ", argv[0],
|
TCL_APPEND_RESULT(
|
||||||
" destPhoto srcImage", (char *) NULL);
|
interp, "usage: ", argv[0], " destPhoto srcImage", (char *)NULL);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get Tcl PhotoImage handle */
|
/* get Tcl PhotoImage handle */
|
||||||
photo = TK_FIND_PHOTO(interp, argv[1]);
|
photo = TK_FIND_PHOTO(interp, argv[1]);
|
||||||
if (photo == NULL) {
|
if (photo == NULL) {
|
||||||
TCL_APPEND_RESULT(
|
TCL_APPEND_RESULT(interp, "destination photo must exist", (char *)NULL);
|
||||||
interp, "destination photo must exist", (char *) NULL
|
|
||||||
);
|
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +131,8 @@ PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp,
|
||||||
block.pixelPtr = (unsigned char *)im->block;
|
block.pixelPtr = (unsigned char *)im->block;
|
||||||
|
|
||||||
if (TK_LT_85) { /* Tk 8.4 */
|
if (TK_LT_85) { /* Tk 8.4 */
|
||||||
TK_PHOTO_PUT_BLOCK_84(photo, &block, 0, 0, block.width, block.height,
|
TK_PHOTO_PUT_BLOCK_84(
|
||||||
TK_PHOTO_COMPOSITE_SET);
|
photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET);
|
||||||
if (strcmp(im->mode, "RGBA") == 0) {
|
if (strcmp(im->mode, "RGBA") == 0) {
|
||||||
/* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */
|
/* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */
|
||||||
/* (fixed in Tk 8.5a3) */
|
/* (fixed in Tk 8.5a3) */
|
||||||
|
@ -145,34 +140,38 @@ PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Tk >=8.5 */
|
/* Tk >=8.5 */
|
||||||
TK_PHOTO_PUT_BLOCK_85(interp, photo, &block, 0, 0, block.width,
|
TK_PHOTO_PUT_BLOCK_85(
|
||||||
block.height, TK_PHOTO_COMPOSITE_SET);
|
interp,
|
||||||
|
photo,
|
||||||
|
&block,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
block.width,
|
||||||
|
block.height,
|
||||||
|
TK_PHOTO_COMPOSITE_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
PyImagingPhotoGet(ClientData clientdata, Tcl_Interp* interp,
|
PyImagingPhotoGet(
|
||||||
int argc, const char **argv)
|
ClientData clientdata, Tcl_Interp *interp, int argc, const char **argv) {
|
||||||
{
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
Tk_PhotoHandle photo;
|
Tk_PhotoHandle photo;
|
||||||
Tk_PhotoImageBlock block;
|
Tk_PhotoImageBlock block;
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
TCL_APPEND_RESULT(interp, "usage: ", argv[0],
|
TCL_APPEND_RESULT(
|
||||||
" srcPhoto destImage", (char *) NULL);
|
interp, "usage: ", argv[0], " srcPhoto destImage", (char *)NULL);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get Tcl PhotoImage handle */
|
/* get Tcl PhotoImage handle */
|
||||||
photo = TK_FIND_PHOTO(interp, argv[1]);
|
photo = TK_FIND_PHOTO(interp, argv[1]);
|
||||||
if (photo == NULL) {
|
if (photo == NULL) {
|
||||||
TCL_APPEND_RESULT(
|
TCL_APPEND_RESULT(interp, "source photo must exist", (char *)NULL);
|
||||||
interp, "source photo must exist", (char *) NULL
|
|
||||||
);
|
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,14 +197,20 @@ PyImagingPhotoGet(ClientData clientdata, Tcl_Interp* interp,
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TkImaging_Init(Tcl_Interp* interp)
|
TkImaging_Init(Tcl_Interp *interp) {
|
||||||
{
|
TCL_CREATE_COMMAND(
|
||||||
TCL_CREATE_COMMAND(interp, "PyImagingPhoto", PyImagingPhotoPut,
|
interp,
|
||||||
(ClientData) 0, (Tcl_CmdDeleteProc*) NULL);
|
"PyImagingPhoto",
|
||||||
TCL_CREATE_COMMAND(interp, "PyImagingPhotoGet", PyImagingPhotoGet,
|
PyImagingPhotoPut,
|
||||||
(ClientData) 0, (Tcl_CmdDeleteProc*) NULL);
|
(ClientData)0,
|
||||||
|
(Tcl_CmdDeleteProc *)NULL);
|
||||||
|
TCL_CREATE_COMMAND(
|
||||||
|
interp,
|
||||||
|
"PyImagingPhotoGet",
|
||||||
|
PyImagingPhotoGet,
|
||||||
|
(ClientData)0,
|
||||||
|
(Tcl_CmdDeleteProc *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -230,8 +235,8 @@ TkImaging_Init(Tcl_Interp* interp)
|
||||||
|
|
||||||
#define TKINTER_PKG "tkinter"
|
#define TKINTER_PKG "tkinter"
|
||||||
|
|
||||||
FARPROC _dfunc(HMODULE lib_handle, const char *func_name)
|
FARPROC
|
||||||
{
|
_dfunc(HMODULE lib_handle, const char *func_name) {
|
||||||
/*
|
/*
|
||||||
* Load function `func_name` from `lib_handle`.
|
* Load function `func_name` from `lib_handle`.
|
||||||
* Set Python exception if we can't find `func_name` in `lib_handle`.
|
* Set Python exception if we can't find `func_name` in `lib_handle`.
|
||||||
|
@ -248,24 +253,26 @@ FARPROC _dfunc(HMODULE lib_handle, const char *func_name)
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_tcl(HMODULE hMod)
|
int
|
||||||
{
|
get_tcl(HMODULE hMod) {
|
||||||
/*
|
/*
|
||||||
* Try to fill Tcl global vars with function pointers. Return 0 for no
|
* Try to fill Tcl global vars with function pointers. Return 0 for no
|
||||||
* functions found, 1 for all functions found, -1 for some but not all
|
* functions found, 1 for all functions found, -1 for some but not all
|
||||||
* functions found.
|
* functions found.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
|
if ((TCL_CREATE_COMMAND =
|
||||||
GetProcAddress(hMod, "Tcl_CreateCommand")) == NULL) {
|
(Tcl_CreateCommand_t)GetProcAddress(hMod, "Tcl_CreateCommand")) == NULL) {
|
||||||
return 0; /* Maybe not Tcl module */
|
return 0; /* Maybe not Tcl module */
|
||||||
}
|
}
|
||||||
return ((TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc(hMod,
|
return ((TCL_APPEND_RESULT =
|
||||||
"Tcl_AppendResult")) == NULL) ? -1 : 1;
|
(Tcl_AppendResult_t)_dfunc(hMod, "Tcl_AppendResult")) == NULL)
|
||||||
|
? -1
|
||||||
|
: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_tk(HMODULE hMod)
|
int
|
||||||
{
|
get_tk(HMODULE hMod) {
|
||||||
/*
|
/*
|
||||||
* Try to fill Tk global vars with function pointers. Return 0 for no
|
* Try to fill Tk global vars with function pointers. Return 0 for no
|
||||||
* functions found, 1 for all functions found, -1 for some but not all
|
* functions found, 1 for all functions found, -1 for some but not all
|
||||||
|
@ -276,23 +283,28 @@ int get_tk(HMODULE hMod)
|
||||||
if (func == NULL) { /* Maybe not Tk module */
|
if (func == NULL) { /* Maybe not Tk module */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((TK_PHOTO_GET_IMAGE = (Tk_PhotoGetImage_t)
|
if ((TK_PHOTO_GET_IMAGE = (Tk_PhotoGetImage_t)_dfunc(hMod, "Tk_PhotoGetImage")) ==
|
||||||
_dfunc(hMod, "Tk_PhotoGetImage")) == NULL) { return -1; };
|
NULL) {
|
||||||
if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
|
return -1;
|
||||||
_dfunc(hMod, "Tk_FindPhoto")) == NULL) { return -1; };
|
};
|
||||||
|
if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)_dfunc(hMod, "Tk_FindPhoto")) == NULL) {
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
TK_LT_85 = GetProcAddress(hMod, "Tk_PhotoPutBlock_Panic") == NULL;
|
TK_LT_85 = GetProcAddress(hMod, "Tk_PhotoPutBlock_Panic") == NULL;
|
||||||
/* Tk_PhotoPutBlock_Panic defined as of 8.5.0 */
|
/* Tk_PhotoPutBlock_Panic defined as of 8.5.0 */
|
||||||
if (TK_LT_85) {
|
if (TK_LT_85) {
|
||||||
TK_PHOTO_PUT_BLOCK_84 = (Tk_PhotoPutBlock_84_t)func;
|
TK_PHOTO_PUT_BLOCK_84 = (Tk_PhotoPutBlock_84_t)func;
|
||||||
return ((TK_PHOTO_SET_SIZE_84 = (Tk_PhotoSetSize_84_t)
|
return ((TK_PHOTO_SET_SIZE_84 =
|
||||||
_dfunc(hMod, "Tk_PhotoSetSize")) == NULL) ? -1 : 1;
|
(Tk_PhotoSetSize_84_t)_dfunc(hMod, "Tk_PhotoSetSize")) == NULL)
|
||||||
|
? -1
|
||||||
|
: 1;
|
||||||
}
|
}
|
||||||
TK_PHOTO_PUT_BLOCK_85 = (Tk_PhotoPutBlock_85_t)func;
|
TK_PHOTO_PUT_BLOCK_85 = (Tk_PhotoPutBlock_85_t)func;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_tkinter_funcs(void)
|
int
|
||||||
{
|
load_tkinter_funcs(void) {
|
||||||
/*
|
/*
|
||||||
* Load Tcl and Tk functions by searching all modules in current process.
|
* Load Tcl and Tk functions by searching all modules in current process.
|
||||||
* Return 0 for success, non-zero for failure.
|
* Return 0 for success, non-zero for failure.
|
||||||
|
@ -353,8 +365,8 @@ int load_tkinter_funcs(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* From module __file__ attribute to char *string for dlopen. */
|
/* From module __file__ attribute to char *string for dlopen. */
|
||||||
char *fname2char(PyObject *fname)
|
char *
|
||||||
{
|
fname2char(PyObject *fname) {
|
||||||
PyObject *bytes;
|
PyObject *bytes;
|
||||||
bytes = PyUnicode_EncodeFSDefault(fname);
|
bytes = PyUnicode_EncodeFSDefault(fname);
|
||||||
if (bytes == NULL) {
|
if (bytes == NULL) {
|
||||||
|
@ -365,8 +377,8 @@ char *fname2char(PyObject *fname)
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
void *_dfunc(void *lib_handle, const char *func_name)
|
void *
|
||||||
{
|
_dfunc(void *lib_handle, const char *func_name) {
|
||||||
/*
|
/*
|
||||||
* Load function `func_name` from `lib_handle`.
|
* Load function `func_name` from `lib_handle`.
|
||||||
* Set Python exception if we can't find `func_name` in `lib_handle`.
|
* Set Python exception if we can't find `func_name` in `lib_handle`.
|
||||||
|
@ -384,35 +396,44 @@ void *_dfunc(void *lib_handle, const char *func_name)
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _func_loader(void *lib)
|
int
|
||||||
{
|
_func_loader(void *lib) {
|
||||||
/*
|
/*
|
||||||
* Fill global function pointers from dynamic lib.
|
* Fill global function pointers from dynamic lib.
|
||||||
* Return 1 if any pointer is NULL, 0 otherwise.
|
* Return 1 if any pointer is NULL, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
|
if ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)_dfunc(lib, "Tcl_CreateCommand")) ==
|
||||||
_dfunc(lib, "Tcl_CreateCommand")) == NULL) { return 1; }
|
NULL) {
|
||||||
if ((TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc(lib,
|
return 1;
|
||||||
"Tcl_AppendResult")) == NULL) { return 1; }
|
}
|
||||||
if ((TK_PHOTO_GET_IMAGE = (Tk_PhotoGetImage_t)
|
if ((TCL_APPEND_RESULT = (Tcl_AppendResult_t)_dfunc(lib, "Tcl_AppendResult")) ==
|
||||||
_dfunc(lib, "Tk_PhotoGetImage")) == NULL) { return 1; }
|
NULL) {
|
||||||
if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
|
return 1;
|
||||||
_dfunc(lib, "Tk_FindPhoto")) == NULL) { return 1; }
|
}
|
||||||
|
if ((TK_PHOTO_GET_IMAGE = (Tk_PhotoGetImage_t)_dfunc(lib, "Tk_PhotoGetImage")) ==
|
||||||
|
NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)_dfunc(lib, "Tk_FindPhoto")) == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/* Tk_PhotoPutBlock_Panic defined as of 8.5.0 */
|
/* Tk_PhotoPutBlock_Panic defined as of 8.5.0 */
|
||||||
TK_LT_85 = (dlsym(lib, "Tk_PhotoPutBlock_Panic") == NULL);
|
TK_LT_85 = (dlsym(lib, "Tk_PhotoPutBlock_Panic") == NULL);
|
||||||
if (TK_LT_85) {
|
if (TK_LT_85) {
|
||||||
return (((TK_PHOTO_PUT_BLOCK_84 = (Tk_PhotoPutBlock_84_t)
|
return (
|
||||||
_dfunc(lib, "Tk_PhotoPutBlock")) == NULL) ||
|
((TK_PHOTO_PUT_BLOCK_84 =
|
||||||
((TK_PHOTO_SET_SIZE_84 = (Tk_PhotoSetSize_84_t)
|
(Tk_PhotoPutBlock_84_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL) ||
|
||||||
_dfunc(lib, "Tk_PhotoSetSize")) == NULL));
|
((TK_PHOTO_SET_SIZE_84 =
|
||||||
|
(Tk_PhotoSetSize_84_t)_dfunc(lib, "Tk_PhotoSetSize")) == NULL));
|
||||||
}
|
}
|
||||||
return ((TK_PHOTO_PUT_BLOCK_85 = (Tk_PhotoPutBlock_85_t)
|
return (
|
||||||
_dfunc(lib, "Tk_PhotoPutBlock")) == NULL);
|
(TK_PHOTO_PUT_BLOCK_85 =
|
||||||
|
(Tk_PhotoPutBlock_85_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_tkinter_funcs(void)
|
int
|
||||||
{
|
load_tkinter_funcs(void) {
|
||||||
/*
|
/*
|
||||||
* Load tkinter global funcs from tkinter compiled module.
|
* Load tkinter global funcs from tkinter compiled module.
|
||||||
* Return 0 for success, non-zero for failure.
|
* Return 0 for success, non-zero for failure.
|
||||||
|
@ -447,8 +468,7 @@ int load_tkinter_funcs(void)
|
||||||
}
|
}
|
||||||
tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
|
tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
|
||||||
if (tkinter_lib == NULL) {
|
if (tkinter_lib == NULL) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError, "Cannot dlopen tkinter module file");
|
||||||
"Cannot dlopen tkinter module file");
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
ret = _func_loader(tkinter_lib);
|
ret = _func_loader(tkinter_lib);
|
||||||
|
|
1525
src/_imaging.c
1525
src/_imaging.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
381
src/_imagingft.c
381
src/_imagingft.c
|
@ -51,15 +51,17 @@
|
||||||
|
|
||||||
#define FT_ERRORDEF(e, v, s) {e, s},
|
#define FT_ERRORDEF(e, v, s) {e, s},
|
||||||
#define FT_ERROR_START_LIST {
|
#define FT_ERROR_START_LIST {
|
||||||
#define FT_ERROR_END_LIST { 0, 0 } };
|
#define FT_ERROR_END_LIST \
|
||||||
|
{ 0, 0 } \
|
||||||
|
} \
|
||||||
|
;
|
||||||
|
|
||||||
#include "libImaging/raqm.h"
|
#include "libImaging/raqm.h"
|
||||||
|
|
||||||
#define LAYOUT_FALLBACK 0
|
#define LAYOUT_FALLBACK 0
|
||||||
#define LAYOUT_RAQM 1
|
#define LAYOUT_RAQM 1
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int index, x_offset, x_advance, y_offset, y_advance;
|
int index, x_offset, x_advance, y_offset, y_advance;
|
||||||
unsigned int cluster;
|
unsigned int cluster;
|
||||||
} GlyphInfo;
|
} GlyphInfo;
|
||||||
|
@ -77,8 +79,7 @@ struct {
|
||||||
static FT_Library library;
|
static FT_Library library;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD FT_Face face;
|
||||||
FT_Face face;
|
|
||||||
unsigned char *font_bytes;
|
unsigned char *font_bytes;
|
||||||
int layout_engine;
|
int layout_engine;
|
||||||
} FontObject;
|
} FontObject;
|
||||||
|
@ -86,32 +87,19 @@ typedef struct {
|
||||||
static PyTypeObject Font_Type;
|
static PyTypeObject Font_Type;
|
||||||
|
|
||||||
typedef const char *(*t_raqm_version_string)(void);
|
typedef const char *(*t_raqm_version_string)(void);
|
||||||
typedef bool (*t_raqm_version_atleast)(unsigned int major,
|
typedef bool (*t_raqm_version_atleast)(
|
||||||
unsigned int minor,
|
unsigned int major, unsigned int minor, unsigned int micro);
|
||||||
unsigned int micro);
|
|
||||||
typedef raqm_t *(*t_raqm_create)(void);
|
typedef raqm_t *(*t_raqm_create)(void);
|
||||||
typedef int (*t_raqm_set_text)(raqm_t *rq,
|
typedef int (*t_raqm_set_text)(raqm_t *rq, const uint32_t *text, size_t len);
|
||||||
const uint32_t *text,
|
typedef bool (*t_raqm_set_text_utf8)(raqm_t *rq, const char *text, size_t len);
|
||||||
size_t len);
|
typedef bool (*t_raqm_set_par_direction)(raqm_t *rq, raqm_direction_t dir);
|
||||||
typedef bool (*t_raqm_set_text_utf8) (raqm_t *rq,
|
typedef bool (*t_raqm_set_language)(
|
||||||
const char *text,
|
raqm_t *rq, const char *lang, size_t start, size_t len);
|
||||||
size_t len);
|
typedef bool (*t_raqm_add_font_feature)(raqm_t *rq, const char *feature, int len);
|
||||||
typedef bool (*t_raqm_set_par_direction) (raqm_t *rq,
|
typedef bool (*t_raqm_set_freetype_face)(raqm_t *rq, FT_Face face);
|
||||||
raqm_direction_t dir);
|
|
||||||
typedef bool (*t_raqm_set_language) (raqm_t *rq,
|
|
||||||
const char *lang,
|
|
||||||
size_t start,
|
|
||||||
size_t len);
|
|
||||||
typedef bool (*t_raqm_add_font_feature) (raqm_t *rq,
|
|
||||||
const char *feature,
|
|
||||||
int len);
|
|
||||||
typedef bool (*t_raqm_set_freetype_face) (raqm_t *rq,
|
|
||||||
FT_Face face);
|
|
||||||
typedef bool (*t_raqm_layout)(raqm_t *rq);
|
typedef bool (*t_raqm_layout)(raqm_t *rq);
|
||||||
typedef raqm_glyph_t* (*t_raqm_get_glyphs) (raqm_t *rq,
|
typedef raqm_glyph_t *(*t_raqm_get_glyphs)(raqm_t *rq, size_t *length);
|
||||||
size_t *length);
|
typedef raqm_glyph_t_01 *(*t_raqm_get_glyphs_01)(raqm_t *rq, size_t *length);
|
||||||
typedef raqm_glyph_t_01* (*t_raqm_get_glyphs_01) (raqm_t *rq,
|
|
||||||
size_t *length);
|
|
||||||
typedef void (*t_raqm_destroy)(raqm_t *rq);
|
typedef void (*t_raqm_destroy)(raqm_t *rq);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -134,13 +122,11 @@ typedef struct {
|
||||||
|
|
||||||
static p_raqm_func p_raqm;
|
static p_raqm_func p_raqm;
|
||||||
|
|
||||||
|
|
||||||
/* round a 26.6 pixel coordinate to the nearest integer */
|
/* round a 26.6 pixel coordinate to the nearest integer */
|
||||||
#define PIXEL(x) ((((x) + 32) & -64) >> 6)
|
#define PIXEL(x) ((((x) + 32) & -64) >> 6)
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
geterror(int code)
|
geterror(int code) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; ft_errors[i].message; i++) {
|
for (i = 0; ft_errors[i].message; i++) {
|
||||||
|
@ -155,8 +141,7 @@ geterror(int code)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setraqm(void)
|
setraqm(void) {
|
||||||
{
|
|
||||||
/* set the static function pointers for dynamic raqm linking */
|
/* set the static function pointers for dynamic raqm linking */
|
||||||
p_raqm.raqm = NULL;
|
p_raqm.raqm = NULL;
|
||||||
|
|
||||||
|
@ -179,15 +164,21 @@ setraqm(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
p_raqm.version_string = (t_raqm_version_string)dlsym(p_raqm.raqm, "raqm_version_string");
|
p_raqm.version_string =
|
||||||
p_raqm.version_atleast = (t_raqm_version_atleast)dlsym(p_raqm.raqm, "raqm_version_atleast");
|
(t_raqm_version_string)dlsym(p_raqm.raqm, "raqm_version_string");
|
||||||
|
p_raqm.version_atleast =
|
||||||
|
(t_raqm_version_atleast)dlsym(p_raqm.raqm, "raqm_version_atleast");
|
||||||
p_raqm.create = (t_raqm_create)dlsym(p_raqm.raqm, "raqm_create");
|
p_raqm.create = (t_raqm_create)dlsym(p_raqm.raqm, "raqm_create");
|
||||||
p_raqm.set_text = (t_raqm_set_text)dlsym(p_raqm.raqm, "raqm_set_text");
|
p_raqm.set_text = (t_raqm_set_text)dlsym(p_raqm.raqm, "raqm_set_text");
|
||||||
p_raqm.set_text_utf8 = (t_raqm_set_text_utf8)dlsym(p_raqm.raqm, "raqm_set_text_utf8");
|
p_raqm.set_text_utf8 =
|
||||||
p_raqm.set_par_direction = (t_raqm_set_par_direction)dlsym(p_raqm.raqm, "raqm_set_par_direction");
|
(t_raqm_set_text_utf8)dlsym(p_raqm.raqm, "raqm_set_text_utf8");
|
||||||
|
p_raqm.set_par_direction =
|
||||||
|
(t_raqm_set_par_direction)dlsym(p_raqm.raqm, "raqm_set_par_direction");
|
||||||
p_raqm.set_language = (t_raqm_set_language)dlsym(p_raqm.raqm, "raqm_set_language");
|
p_raqm.set_language = (t_raqm_set_language)dlsym(p_raqm.raqm, "raqm_set_language");
|
||||||
p_raqm.add_font_feature = (t_raqm_add_font_feature)dlsym(p_raqm.raqm, "raqm_add_font_feature");
|
p_raqm.add_font_feature =
|
||||||
p_raqm.set_freetype_face = (t_raqm_set_freetype_face)dlsym(p_raqm.raqm, "raqm_set_freetype_face");
|
(t_raqm_add_font_feature)dlsym(p_raqm.raqm, "raqm_add_font_feature");
|
||||||
|
p_raqm.set_freetype_face =
|
||||||
|
(t_raqm_set_freetype_face)dlsym(p_raqm.raqm, "raqm_set_freetype_face");
|
||||||
p_raqm.layout = (t_raqm_layout)dlsym(p_raqm.raqm, "raqm_layout");
|
p_raqm.layout = (t_raqm_layout)dlsym(p_raqm.raqm, "raqm_layout");
|
||||||
p_raqm.destroy = (t_raqm_destroy)dlsym(p_raqm.raqm, "raqm_destroy");
|
p_raqm.destroy = (t_raqm_destroy)dlsym(p_raqm.raqm, "raqm_destroy");
|
||||||
if (dlsym(p_raqm.raqm, "raqm_index_to_position")) {
|
if (dlsym(p_raqm.raqm, "raqm_index_to_position")) {
|
||||||
|
@ -195,52 +186,50 @@ setraqm(void)
|
||||||
p_raqm.version = 2;
|
p_raqm.version = 2;
|
||||||
} else {
|
} else {
|
||||||
p_raqm.version = 1;
|
p_raqm.version = 1;
|
||||||
p_raqm.get_glyphs_01 = (t_raqm_get_glyphs_01)dlsym(p_raqm.raqm, "raqm_get_glyphs");
|
p_raqm.get_glyphs_01 =
|
||||||
|
(t_raqm_get_glyphs_01)dlsym(p_raqm.raqm, "raqm_get_glyphs");
|
||||||
}
|
}
|
||||||
if (dlerror() ||
|
if (dlerror() ||
|
||||||
!(p_raqm.create &&
|
!(p_raqm.create && p_raqm.set_text && p_raqm.set_text_utf8 &&
|
||||||
p_raqm.set_text &&
|
p_raqm.set_par_direction && p_raqm.set_language && p_raqm.add_font_feature &&
|
||||||
p_raqm.set_text_utf8 &&
|
p_raqm.set_freetype_face && p_raqm.layout &&
|
||||||
p_raqm.set_par_direction &&
|
(p_raqm.get_glyphs || p_raqm.get_glyphs_01) && p_raqm.destroy)) {
|
||||||
p_raqm.set_language &&
|
|
||||||
p_raqm.add_font_feature &&
|
|
||||||
p_raqm.set_freetype_face &&
|
|
||||||
p_raqm.layout &&
|
|
||||||
(p_raqm.get_glyphs || p_raqm.get_glyphs_01) &&
|
|
||||||
p_raqm.destroy)) {
|
|
||||||
dlclose(p_raqm.raqm);
|
dlclose(p_raqm.raqm);
|
||||||
p_raqm.raqm = NULL;
|
p_raqm.raqm = NULL;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
p_raqm.version_string = (t_raqm_version_string)GetProcAddress(p_raqm.raqm, "raqm_version_string");
|
p_raqm.version_string =
|
||||||
p_raqm.version_atleast = (t_raqm_version_atleast)GetProcAddress(p_raqm.raqm, "raqm_version_atleast");
|
(t_raqm_version_string)GetProcAddress(p_raqm.raqm, "raqm_version_string");
|
||||||
|
p_raqm.version_atleast =
|
||||||
|
(t_raqm_version_atleast)GetProcAddress(p_raqm.raqm, "raqm_version_atleast");
|
||||||
p_raqm.create = (t_raqm_create)GetProcAddress(p_raqm.raqm, "raqm_create");
|
p_raqm.create = (t_raqm_create)GetProcAddress(p_raqm.raqm, "raqm_create");
|
||||||
p_raqm.set_text = (t_raqm_set_text)GetProcAddress(p_raqm.raqm, "raqm_set_text");
|
p_raqm.set_text = (t_raqm_set_text)GetProcAddress(p_raqm.raqm, "raqm_set_text");
|
||||||
p_raqm.set_text_utf8 = (t_raqm_set_text_utf8)GetProcAddress(p_raqm.raqm, "raqm_set_text_utf8");
|
p_raqm.set_text_utf8 =
|
||||||
p_raqm.set_par_direction = (t_raqm_set_par_direction)GetProcAddress(p_raqm.raqm, "raqm_set_par_direction");
|
(t_raqm_set_text_utf8)GetProcAddress(p_raqm.raqm, "raqm_set_text_utf8");
|
||||||
p_raqm.set_language = (t_raqm_set_language)GetProcAddress(p_raqm.raqm, "raqm_set_language");
|
p_raqm.set_par_direction =
|
||||||
p_raqm.add_font_feature = (t_raqm_add_font_feature)GetProcAddress(p_raqm.raqm, "raqm_add_font_feature");
|
(t_raqm_set_par_direction)GetProcAddress(p_raqm.raqm, "raqm_set_par_direction");
|
||||||
p_raqm.set_freetype_face = (t_raqm_set_freetype_face)GetProcAddress(p_raqm.raqm, "raqm_set_freetype_face");
|
p_raqm.set_language =
|
||||||
|
(t_raqm_set_language)GetProcAddress(p_raqm.raqm, "raqm_set_language");
|
||||||
|
p_raqm.add_font_feature =
|
||||||
|
(t_raqm_add_font_feature)GetProcAddress(p_raqm.raqm, "raqm_add_font_feature");
|
||||||
|
p_raqm.set_freetype_face =
|
||||||
|
(t_raqm_set_freetype_face)GetProcAddress(p_raqm.raqm, "raqm_set_freetype_face");
|
||||||
p_raqm.layout = (t_raqm_layout)GetProcAddress(p_raqm.raqm, "raqm_layout");
|
p_raqm.layout = (t_raqm_layout)GetProcAddress(p_raqm.raqm, "raqm_layout");
|
||||||
p_raqm.destroy = (t_raqm_destroy)GetProcAddress(p_raqm.raqm, "raqm_destroy");
|
p_raqm.destroy = (t_raqm_destroy)GetProcAddress(p_raqm.raqm, "raqm_destroy");
|
||||||
if (GetProcAddress(p_raqm.raqm, "raqm_index_to_position")) {
|
if (GetProcAddress(p_raqm.raqm, "raqm_index_to_position")) {
|
||||||
p_raqm.get_glyphs = (t_raqm_get_glyphs)GetProcAddress(p_raqm.raqm, "raqm_get_glyphs");
|
p_raqm.get_glyphs =
|
||||||
|
(t_raqm_get_glyphs)GetProcAddress(p_raqm.raqm, "raqm_get_glyphs");
|
||||||
p_raqm.version = 2;
|
p_raqm.version = 2;
|
||||||
} else {
|
} else {
|
||||||
p_raqm.version = 1;
|
p_raqm.version = 1;
|
||||||
p_raqm.get_glyphs_01 = (t_raqm_get_glyphs_01)GetProcAddress(p_raqm.raqm, "raqm_get_glyphs");
|
p_raqm.get_glyphs_01 =
|
||||||
|
(t_raqm_get_glyphs_01)GetProcAddress(p_raqm.raqm, "raqm_get_glyphs");
|
||||||
}
|
}
|
||||||
if (!(p_raqm.create &&
|
if (!(p_raqm.create && p_raqm.set_text && p_raqm.set_text_utf8 &&
|
||||||
p_raqm.set_text &&
|
p_raqm.set_par_direction && p_raqm.set_language && p_raqm.add_font_feature &&
|
||||||
p_raqm.set_text_utf8 &&
|
p_raqm.set_freetype_face && p_raqm.layout &&
|
||||||
p_raqm.set_par_direction &&
|
(p_raqm.get_glyphs || p_raqm.get_glyphs_01) && p_raqm.destroy)) {
|
||||||
p_raqm.set_language &&
|
|
||||||
p_raqm.add_font_feature &&
|
|
||||||
p_raqm.set_freetype_face &&
|
|
||||||
p_raqm.layout &&
|
|
||||||
(p_raqm.get_glyphs || p_raqm.get_glyphs_01) &&
|
|
||||||
p_raqm.destroy)) {
|
|
||||||
FreeLibrary(p_raqm.raqm);
|
FreeLibrary(p_raqm.raqm);
|
||||||
p_raqm.raqm = NULL;
|
p_raqm.raqm = NULL;
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -251,8 +240,7 @@ setraqm(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
getfont(PyObject* self_, PyObject* args, PyObject* kw)
|
getfont(PyObject *self_, PyObject *args, PyObject *kw) {
|
||||||
{
|
|
||||||
/* create a font object from a file name and a size (in pixels) */
|
/* create a font object from a file name and a size (in pixels) */
|
||||||
|
|
||||||
FontObject *self;
|
FontObject *self;
|
||||||
|
@ -266,22 +254,26 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
|
||||||
unsigned char *font_bytes;
|
unsigned char *font_bytes;
|
||||||
Py_ssize_t font_bytes_size = 0;
|
Py_ssize_t font_bytes_size = 0;
|
||||||
static char *kwlist[] = {
|
static char *kwlist[] = {
|
||||||
"filename", "size", "index", "encoding", "font_bytes",
|
"filename", "size", "index", "encoding", "font_bytes", "layout_engine", NULL};
|
||||||
"layout_engine", NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!library) {
|
if (!library) {
|
||||||
PyErr_SetString(
|
PyErr_SetString(PyExc_OSError, "failed to initialize FreeType library");
|
||||||
PyExc_OSError,
|
|
||||||
"failed to initialize FreeType library"
|
|
||||||
);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "etn|nsy#n", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(
|
||||||
Py_FileSystemDefaultEncoding, &filename,
|
args,
|
||||||
&size, &index, &encoding, &font_bytes,
|
kw,
|
||||||
&font_bytes_size, &layout_engine)) {
|
"etn|nsy#n",
|
||||||
|
kwlist,
|
||||||
|
Py_FileSystemDefaultEncoding,
|
||||||
|
&filename,
|
||||||
|
&size,
|
||||||
|
&index,
|
||||||
|
&encoding,
|
||||||
|
&font_bytes,
|
||||||
|
&font_bytes_size,
|
||||||
|
&layout_engine)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,8 +300,12 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
|
||||||
}
|
}
|
||||||
if (!error) {
|
if (!error) {
|
||||||
memcpy(self->font_bytes, font_bytes, (size_t)font_bytes_size);
|
memcpy(self->font_bytes, font_bytes, (size_t)font_bytes_size);
|
||||||
error = FT_New_Memory_Face(library, (FT_Byte*)self->font_bytes,
|
error = FT_New_Memory_Face(
|
||||||
font_bytes_size, index, &self->face);
|
library,
|
||||||
|
(FT_Byte *)self->font_bytes,
|
||||||
|
font_bytes_size,
|
||||||
|
index,
|
||||||
|
&self->face);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,9 +314,8 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error && encoding && strlen((char *)encoding) == 4) {
|
if (!error && encoding && strlen((char *)encoding) == 4) {
|
||||||
FT_Encoding encoding_tag = FT_MAKE_TAG(
|
FT_Encoding encoding_tag =
|
||||||
encoding[0], encoding[1], encoding[2], encoding[3]
|
FT_MAKE_TAG(encoding[0], encoding[1], encoding[2], encoding[3]);
|
||||||
);
|
|
||||||
error = FT_Select_Charmap(self->face, encoding_tag);
|
error = FT_Select_Charmap(self->face, encoding_tag);
|
||||||
}
|
}
|
||||||
if (filename) {
|
if (filename) {
|
||||||
|
@ -340,8 +335,7 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
font_getchar(PyObject* string, int index, FT_ULong* char_out)
|
font_getchar(PyObject *string, int index, FT_ULong *char_out) {
|
||||||
{
|
|
||||||
if (PyUnicode_Check(string)) {
|
if (PyUnicode_Check(string)) {
|
||||||
if (index >= PyUnicode_GET_LENGTH(string)) {
|
if (index >= PyUnicode_GET_LENGTH(string)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -353,9 +347,15 @@ font_getchar(PyObject* string, int index, FT_ULong* char_out)
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *features,
|
text_layout_raqm(
|
||||||
const char* lang, GlyphInfo **glyph_info, int mask, int color)
|
PyObject *string,
|
||||||
{
|
FontObject *self,
|
||||||
|
const char *dir,
|
||||||
|
PyObject *features,
|
||||||
|
const char *lang,
|
||||||
|
GlyphInfo **glyph_info,
|
||||||
|
int mask,
|
||||||
|
int color) {
|
||||||
size_t i = 0, count = 0, start = 0;
|
size_t i = 0, count = 0, start = 0;
|
||||||
raqm_t *rq;
|
raqm_t *rq;
|
||||||
raqm_glyph_t *glyphs = NULL;
|
raqm_glyph_t *glyphs = NULL;
|
||||||
|
@ -388,8 +388,7 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "expected string");
|
PyErr_SetString(PyExc_TypeError, "expected string");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -403,11 +402,14 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *
|
||||||
} else if (strcmp(dir, "ttb") == 0) {
|
} else if (strcmp(dir, "ttb") == 0) {
|
||||||
direction = RAQM_DIRECTION_TTB;
|
direction = RAQM_DIRECTION_TTB;
|
||||||
if (p_raqm.version_atleast == NULL || !(*p_raqm.version_atleast)(0, 7, 0)) {
|
if (p_raqm.version_atleast == NULL || !(*p_raqm.version_atleast)(0, 7, 0)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "libraqm 0.7 or greater required for 'ttb' direction");
|
PyErr_SetString(
|
||||||
|
PyExc_ValueError,
|
||||||
|
"libraqm 0.7 or greater required for 'ttb' direction");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_ValueError, "direction must be either 'rtl', 'ltr' or 'ttb'");
|
PyErr_SetString(
|
||||||
|
PyExc_ValueError, "direction must be either 'rtl', 'ltr' or 'ttb'");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,9 +512,15 @@ failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
text_layout_fallback(PyObject* string, FontObject* self, const char* dir, PyObject *features,
|
text_layout_fallback(
|
||||||
const char* lang, GlyphInfo **glyph_info, int mask, int color)
|
PyObject *string,
|
||||||
{
|
FontObject *self,
|
||||||
|
const char *dir,
|
||||||
|
PyObject *features,
|
||||||
|
const char *lang,
|
||||||
|
GlyphInfo **glyph_info,
|
||||||
|
int mask,
|
||||||
|
int color) {
|
||||||
int error, load_flags;
|
int error, load_flags;
|
||||||
FT_ULong ch;
|
FT_ULong ch;
|
||||||
Py_ssize_t count;
|
Py_ssize_t count;
|
||||||
|
@ -522,7 +530,10 @@ text_layout_fallback(PyObject* string, FontObject* self, const char* dir, PyObje
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (features != Py_None || dir != NULL || lang != NULL) {
|
if (features != Py_None || dir != NULL || lang != NULL) {
|
||||||
PyErr_SetString(PyExc_KeyError, "setting text direction, language or font features is not supported without libraqm");
|
PyErr_SetString(
|
||||||
|
PyExc_KeyError,
|
||||||
|
"setting text direction, language or font features is not supported "
|
||||||
|
"without libraqm");
|
||||||
}
|
}
|
||||||
if (!PyUnicode_Check(string)) {
|
if (!PyUnicode_Check(string)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "expected string");
|
PyErr_SetString(PyExc_TypeError, "expected string");
|
||||||
|
@ -564,8 +575,12 @@ text_layout_fallback(PyObject* string, FontObject* self, const char* dir, PyObje
|
||||||
(*glyph_info)[i].y_offset = 0;
|
(*glyph_info)[i].y_offset = 0;
|
||||||
if (kerning && last_index && (*glyph_info)[i].index) {
|
if (kerning && last_index && (*glyph_info)[i].index) {
|
||||||
FT_Vector delta;
|
FT_Vector delta;
|
||||||
if (FT_Get_Kerning(self->face, last_index, (*glyph_info)[i].index,
|
if (FT_Get_Kerning(
|
||||||
ft_kerning_default,&delta) == 0) {
|
self->face,
|
||||||
|
last_index,
|
||||||
|
(*glyph_info)[i].index,
|
||||||
|
ft_kerning_default,
|
||||||
|
&delta) == 0) {
|
||||||
(*glyph_info)[i - 1].x_advance += PIXEL(delta.x);
|
(*glyph_info)[i - 1].x_advance += PIXEL(delta.x);
|
||||||
(*glyph_info)[i - 1].y_advance += PIXEL(delta.y);
|
(*glyph_info)[i - 1].y_advance += PIXEL(delta.y);
|
||||||
}
|
}
|
||||||
|
@ -581,22 +596,29 @@ text_layout_fallback(PyObject* string, FontObject* self, const char* dir, PyObje
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
text_layout(PyObject* string, FontObject* self, const char* dir, PyObject *features,
|
text_layout(
|
||||||
const char* lang, GlyphInfo **glyph_info, int mask, int color)
|
PyObject *string,
|
||||||
{
|
FontObject *self,
|
||||||
|
const char *dir,
|
||||||
|
PyObject *features,
|
||||||
|
const char *lang,
|
||||||
|
GlyphInfo **glyph_info,
|
||||||
|
int mask,
|
||||||
|
int color) {
|
||||||
size_t count;
|
size_t count;
|
||||||
|
|
||||||
if (p_raqm.raqm && self->layout_engine == LAYOUT_RAQM) {
|
if (p_raqm.raqm && self->layout_engine == LAYOUT_RAQM) {
|
||||||
count = text_layout_raqm(string, self, dir, features, lang, glyph_info, mask, color);
|
count = text_layout_raqm(
|
||||||
|
string, self, dir, features, lang, glyph_info, mask, color);
|
||||||
} else {
|
} else {
|
||||||
count = text_layout_fallback(string, self, dir, features, lang, glyph_info, mask, color);
|
count = text_layout_fallback(
|
||||||
|
string, self, dir, features, lang, glyph_info, mask, color);
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getlength(FontObject* self, PyObject* args)
|
font_getlength(FontObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
int length; /* length along primary axis, in 26.6 precision */
|
int length; /* length along primary axis, in 26.6 precision */
|
||||||
GlyphInfo *glyph_info = NULL; /* computed text layout */
|
GlyphInfo *glyph_info = NULL; /* computed text layout */
|
||||||
size_t i, count; /* glyph_info index and length */
|
size_t i, count; /* glyph_info index and length */
|
||||||
|
@ -611,7 +633,8 @@ font_getlength(FontObject* self, PyObject* args)
|
||||||
|
|
||||||
/* calculate size and bearing for a given string */
|
/* calculate size and bearing for a given string */
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|zzOz:getlength", &string, &mode, &dir, &features, &lang)) {
|
if (!PyArg_ParseTuple(
|
||||||
|
args, "O|zzOz:getlength", &string, &mode, &dir, &features, &lang)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,8 +666,7 @@ font_getlength(FontObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getsize(FontObject* self, PyObject* args)
|
font_getsize(FontObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
int position; /* pen position along primary axis, in 26.6 precision */
|
int position; /* pen position along primary axis, in 26.6 precision */
|
||||||
int advanced; /* pen position along primary axis, in pixels */
|
int advanced; /* pen position along primary axis, in pixels */
|
||||||
int px, py; /* position of current glyph, in pixels */
|
int px, py; /* position of current glyph, in pixels */
|
||||||
|
@ -669,7 +691,8 @@ font_getsize(FontObject* self, PyObject* args)
|
||||||
|
|
||||||
/* calculate size and bearing for a given string */
|
/* calculate size and bearing for a given string */
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|zzOzz:getsize", &string, &mode, &dir, &features, &lang, &anchor)) {
|
if (!PyArg_ParseTuple(
|
||||||
|
args, "O|zzOzz:getsize", &string, &mode, &dir, &features, &lang, &anchor)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,7 +815,10 @@ font_getsize(FontObject* self, PyObject* args)
|
||||||
y_anchor = y_max;
|
y_anchor = y_max;
|
||||||
break;
|
break;
|
||||||
case 'm': // middle (ascender + descender) / 2
|
case 'm': // middle (ascender + descender) / 2
|
||||||
y_anchor = PIXEL((self->face->size->metrics.ascender + self->face->size->metrics.descender) / 2);
|
y_anchor = PIXEL(
|
||||||
|
(self->face->size->metrics.ascender +
|
||||||
|
self->face->size->metrics.descender) /
|
||||||
|
2);
|
||||||
break;
|
break;
|
||||||
case 's': // horizontal baseline
|
case 's': // horizontal baseline
|
||||||
y_anchor = 0;
|
y_anchor = 0;
|
||||||
|
@ -844,9 +870,10 @@ font_getsize(FontObject* self, PyObject* args)
|
||||||
|
|
||||||
return Py_BuildValue(
|
return Py_BuildValue(
|
||||||
"(ii)(ii)",
|
"(ii)(ii)",
|
||||||
(x_max - x_min), (y_max - y_min),
|
(x_max - x_min),
|
||||||
(-x_anchor + x_min), -(-y_anchor + y_max)
|
(y_max - y_min),
|
||||||
);
|
(-x_anchor + x_min),
|
||||||
|
-(-y_anchor + y_max));
|
||||||
|
|
||||||
bad_anchor:
|
bad_anchor:
|
||||||
PyErr_Format(PyExc_ValueError, "bad anchor specified: %s", anchor);
|
PyErr_Format(PyExc_ValueError, "bad anchor specified: %s", anchor);
|
||||||
|
@ -854,8 +881,7 @@ bad_anchor:
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_render(FontObject* self, PyObject* args)
|
font_render(FontObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
int x, y; /* pen position, in 26.6 precision */
|
int x, y; /* pen position, in 26.6 precision */
|
||||||
int px, py; /* position of current glyph, in pixels */
|
int px, py; /* position of current glyph, in pixels */
|
||||||
int x_min, y_max; /* text offset in 26.6 precision */
|
int x_min, y_max; /* text offset in 26.6 precision */
|
||||||
|
@ -891,8 +917,17 @@ font_render(FontObject* self, PyObject* args)
|
||||||
/* render string into given buffer (the buffer *must* have
|
/* render string into given buffer (the buffer *must* have
|
||||||
the right size, or this will crash) */
|
the right size, or this will crash) */
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "On|zzOziL:render", &string, &id, &mode, &dir, &features, &lang,
|
if (!PyArg_ParseTuple(
|
||||||
&stroke_width, &foreground_ink_long)) {
|
args,
|
||||||
|
"On|zzOziL:render",
|
||||||
|
&string,
|
||||||
|
&id,
|
||||||
|
&mode,
|
||||||
|
&dir,
|
||||||
|
&features,
|
||||||
|
&lang,
|
||||||
|
&stroke_width,
|
||||||
|
&foreground_ink_long)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,7 +943,8 @@ font_render(FontObject* self, PyObject* args)
|
||||||
foreground_color.red = ink[0];
|
foreground_color.red = ink[0];
|
||||||
foreground_color.green = ink[1];
|
foreground_color.green = ink[1];
|
||||||
foreground_color.blue = ink[2];
|
foreground_color.blue = ink[2];
|
||||||
foreground_color.alpha = (FT_Byte) 255; /* ink alpha is handled in ImageDraw.text */
|
foreground_color.alpha =
|
||||||
|
(FT_Byte)255; /* ink alpha is handled in ImageDraw.text */
|
||||||
FT_Palette_Set_Foreground_Color(self->face, foreground_color);
|
FT_Palette_Set_Foreground_Color(self->face, foreground_color);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -927,7 +963,12 @@ font_render(FontObject* self, PyObject* args)
|
||||||
return geterror(error);
|
return geterror(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Stroker_Set(stroker, (FT_Fixed)stroke_width*64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
|
FT_Stroker_Set(
|
||||||
|
stroker,
|
||||||
|
(FT_Fixed)stroke_width * 64,
|
||||||
|
FT_STROKER_LINECAP_ROUND,
|
||||||
|
FT_STROKER_LINEJOIN_ROUND,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
im = (Imaging)id;
|
im = (Imaging)id;
|
||||||
|
@ -950,7 +991,8 @@ font_render(FontObject* self, PyObject* args)
|
||||||
px = PIXEL(x + glyph_info[i].x_offset);
|
px = PIXEL(x + glyph_info[i].x_offset);
|
||||||
py = PIXEL(y + glyph_info[i].y_offset);
|
py = PIXEL(y + glyph_info[i].y_offset);
|
||||||
|
|
||||||
error = FT_Load_Glyph(self->face, glyph_info[i].index, load_flags | FT_LOAD_RENDER);
|
error =
|
||||||
|
FT_Load_Glyph(self->face, glyph_info[i].index, load_flags | FT_LOAD_RENDER);
|
||||||
if (error) {
|
if (error) {
|
||||||
return geterror(error);
|
return geterror(error);
|
||||||
}
|
}
|
||||||
|
@ -1030,9 +1072,7 @@ font_render(FontObject* self, PyObject* args)
|
||||||
case FT_PIXEL_MODE_GRAY2:
|
case FT_PIXEL_MODE_GRAY2:
|
||||||
case FT_PIXEL_MODE_GRAY4:
|
case FT_PIXEL_MODE_GRAY4:
|
||||||
if (!bitmap_converted_ready) {
|
if (!bitmap_converted_ready) {
|
||||||
|
#if FREETYPE_MAJOR > 2 || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 6)
|
||||||
#if FREETYPE_MAJOR > 2 ||\
|
|
||||||
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 6)
|
|
||||||
FT_Bitmap_Init(&bitmap_converted);
|
FT_Bitmap_Init(&bitmap_converted);
|
||||||
#else
|
#else
|
||||||
FT_Bitmap_New(&bitmap_converted);
|
FT_Bitmap_New(&bitmap_converted);
|
||||||
|
@ -1091,9 +1131,12 @@ font_render(FontObject* self, PyObject* args)
|
||||||
for (k = x0; k < x1; k++) {
|
for (k = x0; k < x1; k++) {
|
||||||
if (target[k * 4 + 3] < source[k * 4 + 3]) {
|
if (target[k * 4 + 3] < source[k * 4 + 3]) {
|
||||||
/* unpremultiply BGRa to RGBA */
|
/* unpremultiply BGRa to RGBA */
|
||||||
target[k * 4 + 0] = CLIP8((255 * (int)source[k * 4 + 2]) / source[k * 4 + 3]);
|
target[k * 4 + 0] = CLIP8(
|
||||||
target[k * 4 + 1] = CLIP8((255 * (int)source[k * 4 + 1]) / source[k * 4 + 3]);
|
(255 * (int)source[k * 4 + 2]) / source[k * 4 + 3]);
|
||||||
target[k * 4 + 2] = CLIP8((255 * (int)source[k * 4 + 0]) / source[k * 4 + 3]);
|
target[k * 4 + 1] = CLIP8(
|
||||||
|
(255 * (int)source[k * 4 + 1]) / source[k * 4 + 3]);
|
||||||
|
target[k * 4 + 2] = CLIP8(
|
||||||
|
(255 * (int)source[k * 4 + 0]) / source[k * 4 + 3]);
|
||||||
target[k * 4 + 3] = source[k * 4 + 3];
|
target[k * 4 + 3] = source[k * 4 + 3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1152,12 +1195,10 @@ glyph_error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FREETYPE_MAJOR > 2 ||\
|
#if FREETYPE_MAJOR > 2 || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 9) || \
|
||||||
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 9) ||\
|
|
||||||
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 9 && FREETYPE_PATCH == 1)
|
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 9 && FREETYPE_PATCH == 1)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getvarnames(FontObject* self)
|
font_getvarnames(FontObject *self) {
|
||||||
{
|
|
||||||
int error;
|
int error;
|
||||||
FT_UInt i, j, num_namedstyles, name_count;
|
FT_UInt i, j, num_namedstyles, name_count;
|
||||||
FT_MM_Var *master;
|
FT_MM_Var *master;
|
||||||
|
@ -1198,8 +1239,7 @@ glyph_error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getvaraxes(FontObject* self)
|
font_getvaraxes(FontObject *self) {
|
||||||
{
|
|
||||||
int error;
|
int error;
|
||||||
FT_UInt i, j, num_axis, name_count;
|
FT_UInt i, j, num_axis, name_count;
|
||||||
FT_MM_Var *master;
|
FT_MM_Var *master;
|
||||||
|
@ -1219,12 +1259,11 @@ glyph_error:
|
||||||
axis = master->axis[i];
|
axis = master->axis[i];
|
||||||
|
|
||||||
list_axis = PyDict_New();
|
list_axis = PyDict_New();
|
||||||
PyDict_SetItemString(list_axis, "minimum",
|
PyDict_SetItemString(
|
||||||
PyLong_FromLong(axis.minimum / 65536));
|
list_axis, "minimum", PyLong_FromLong(axis.minimum / 65536));
|
||||||
PyDict_SetItemString(list_axis, "default",
|
PyDict_SetItemString(list_axis, "default", PyLong_FromLong(axis.def / 65536));
|
||||||
PyLong_FromLong(axis.def / 65536));
|
PyDict_SetItemString(
|
||||||
PyDict_SetItemString(list_axis, "maximum",
|
list_axis, "maximum", PyLong_FromLong(axis.maximum / 65536));
|
||||||
PyLong_FromLong(axis.maximum / 65536));
|
|
||||||
|
|
||||||
for (j = 0; j < name_count; j++) {
|
for (j = 0; j < name_count; j++) {
|
||||||
error = FT_Get_Sfnt_Name(self->face, j, &name);
|
error = FT_Get_Sfnt_Name(self->face, j, &name);
|
||||||
|
@ -1248,8 +1287,7 @@ glyph_error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_setvarname(FontObject* self, PyObject* args)
|
font_setvarname(FontObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
int instance_index;
|
int instance_index;
|
||||||
|
@ -1267,8 +1305,7 @@ glyph_error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_setvaraxes(FontObject* self, PyObject* args)
|
font_setvaraxes(FontObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
PyObject *axes, *item;
|
PyObject *axes, *item;
|
||||||
|
@ -1317,8 +1354,7 @@ glyph_error:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
font_dealloc(FontObject* self)
|
font_dealloc(FontObject *self) {
|
||||||
{
|
|
||||||
if (self->face) {
|
if (self->face) {
|
||||||
FT_Done_Face(self->face);
|
FT_Done_Face(self->face);
|
||||||
}
|
}
|
||||||
|
@ -1332,20 +1368,17 @@ static PyMethodDef font_methods[] = {
|
||||||
{"render", (PyCFunction)font_render, METH_VARARGS},
|
{"render", (PyCFunction)font_render, METH_VARARGS},
|
||||||
{"getsize", (PyCFunction)font_getsize, METH_VARARGS},
|
{"getsize", (PyCFunction)font_getsize, METH_VARARGS},
|
||||||
{"getlength", (PyCFunction)font_getlength, METH_VARARGS},
|
{"getlength", (PyCFunction)font_getlength, METH_VARARGS},
|
||||||
#if FREETYPE_MAJOR > 2 ||\
|
#if FREETYPE_MAJOR > 2 || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 9) || \
|
||||||
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 9) ||\
|
|
||||||
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 9 && FREETYPE_PATCH == 1)
|
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 9 && FREETYPE_PATCH == 1)
|
||||||
{"getvarnames", (PyCFunction)font_getvarnames, METH_NOARGS},
|
{"getvarnames", (PyCFunction)font_getvarnames, METH_NOARGS},
|
||||||
{"getvaraxes", (PyCFunction)font_getvaraxes, METH_NOARGS},
|
{"getvaraxes", (PyCFunction)font_getvaraxes, METH_NOARGS},
|
||||||
{"setvarname", (PyCFunction)font_setvarname, METH_VARARGS},
|
{"setvarname", (PyCFunction)font_setvarname, METH_VARARGS},
|
||||||
{"setvaraxes", (PyCFunction)font_setvaraxes, METH_VARARGS},
|
{"setvaraxes", (PyCFunction)font_setvaraxes, METH_VARARGS},
|
||||||
#endif
|
#endif
|
||||||
{NULL, NULL}
|
{NULL, NULL}};
|
||||||
};
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getattr_family(FontObject* self, void* closure)
|
font_getattr_family(FontObject *self, void *closure) {
|
||||||
{
|
|
||||||
if (self->face->family_name) {
|
if (self->face->family_name) {
|
||||||
return PyUnicode_FromString(self->face->family_name);
|
return PyUnicode_FromString(self->face->family_name);
|
||||||
}
|
}
|
||||||
|
@ -1353,8 +1386,7 @@ font_getattr_family(FontObject* self, void* closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getattr_style(FontObject* self, void* closure)
|
font_getattr_style(FontObject *self, void *closure) {
|
||||||
{
|
|
||||||
if (self->face->style_name) {
|
if (self->face->style_name) {
|
||||||
return PyUnicode_FromString(self->face->style_name);
|
return PyUnicode_FromString(self->face->style_name);
|
||||||
}
|
}
|
||||||
|
@ -1362,39 +1394,32 @@ font_getattr_style(FontObject* self, void* closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getattr_ascent(FontObject* self, void* closure)
|
font_getattr_ascent(FontObject *self, void *closure) {
|
||||||
{
|
|
||||||
return PyLong_FromLong(PIXEL(self->face->size->metrics.ascender));
|
return PyLong_FromLong(PIXEL(self->face->size->metrics.ascender));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getattr_descent(FontObject* self, void* closure)
|
font_getattr_descent(FontObject *self, void *closure) {
|
||||||
{
|
|
||||||
return PyLong_FromLong(-PIXEL(self->face->size->metrics.descender));
|
return PyLong_FromLong(-PIXEL(self->face->size->metrics.descender));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getattr_height(FontObject* self, void* closure)
|
font_getattr_height(FontObject *self, void *closure) {
|
||||||
{
|
|
||||||
return PyLong_FromLong(PIXEL(self->face->size->metrics.height));
|
return PyLong_FromLong(PIXEL(self->face->size->metrics.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getattr_x_ppem(FontObject* self, void* closure)
|
font_getattr_x_ppem(FontObject *self, void *closure) {
|
||||||
{
|
|
||||||
return PyLong_FromLong(self->face->size->metrics.x_ppem);
|
return PyLong_FromLong(self->face->size->metrics.x_ppem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getattr_y_ppem(FontObject* self, void* closure)
|
font_getattr_y_ppem(FontObject *self, void *closure) {
|
||||||
{
|
|
||||||
return PyLong_FromLong(self->face->size->metrics.y_ppem);
|
return PyLong_FromLong(self->face->size->metrics.y_ppem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
font_getattr_glyphs(FontObject* self, void* closure)
|
font_getattr_glyphs(FontObject *self, void *closure) {
|
||||||
{
|
|
||||||
return PyLong_FromLong(self->face->num_glyphs);
|
return PyLong_FromLong(self->face->num_glyphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1407,12 +1432,12 @@ static struct PyGetSetDef font_getsetters[] = {
|
||||||
{"x_ppem", (getter)font_getattr_x_ppem},
|
{"x_ppem", (getter)font_getattr_x_ppem},
|
||||||
{"y_ppem", (getter)font_getattr_y_ppem},
|
{"y_ppem", (getter)font_getattr_y_ppem},
|
||||||
{"glyphs", (getter)font_getattr_glyphs},
|
{"glyphs", (getter)font_getattr_glyphs},
|
||||||
{ NULL }
|
{NULL}};
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject Font_Type = {
|
static PyTypeObject Font_Type = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "Font",
|
||||||
"Font", sizeof(FontObject), 0,
|
sizeof(FontObject),
|
||||||
|
0,
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)font_dealloc, /* tp_dealloc */
|
(destructor)font_dealloc, /* tp_dealloc */
|
||||||
0, /* tp_print */
|
0, /* tp_print */
|
||||||
|
@ -1443,9 +1468,7 @@ static PyTypeObject Font_Type = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMethodDef _functions[] = {
|
static PyMethodDef _functions[] = {
|
||||||
{"getfont", (PyCFunction) getfont, METH_VARARGS|METH_KEYWORDS},
|
{"getfont", (PyCFunction)getfont, METH_VARARGS | METH_KEYWORDS}, {NULL, NULL}};
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setup_module(PyObject *m) {
|
setup_module(PyObject *m) {
|
||||||
|
@ -1467,12 +1490,12 @@ setup_module(PyObject* m) {
|
||||||
v = PyUnicode_FromFormat("%d.%d.%d", major, minor, patch);
|
v = PyUnicode_FromFormat("%d.%d.%d", major, minor, patch);
|
||||||
PyDict_SetItemString(d, "freetype2_version", v);
|
PyDict_SetItemString(d, "freetype2_version", v);
|
||||||
|
|
||||||
|
|
||||||
setraqm();
|
setraqm();
|
||||||
v = PyBool_FromLong(!!p_raqm.raqm);
|
v = PyBool_FromLong(!!p_raqm.raqm);
|
||||||
PyDict_SetItemString(d, "HAVE_RAQM", v);
|
PyDict_SetItemString(d, "HAVE_RAQM", v);
|
||||||
if (p_raqm.version_string) {
|
if (p_raqm.version_string) {
|
||||||
PyDict_SetItemString(d, "raqm_version", PyUnicode_FromString(p_raqm.version_string()));
|
PyDict_SetItemString(
|
||||||
|
d, "raqm_version", PyUnicode_FromString(p_raqm.version_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -24,22 +24,21 @@
|
||||||
#define MIN_INT32 -2147483648.0
|
#define MIN_INT32 -2147483648.0
|
||||||
|
|
||||||
#define UNOP(name, op, type) \
|
#define UNOP(name, op, type) \
|
||||||
void name(Imaging out, Imaging im1)\
|
void name(Imaging out, Imaging im1) { \
|
||||||
{\
|
|
||||||
int x, y; \
|
int x, y; \
|
||||||
for (y = 0; y < out->ysize; y++) { \
|
for (y = 0; y < out->ysize; y++) { \
|
||||||
type *p0 = (type *)out->image[y]; \
|
type *p0 = (type *)out->image[y]; \
|
||||||
type *p1 = (type *)im1->image[y]; \
|
type *p1 = (type *)im1->image[y]; \
|
||||||
for (x = 0; x < out->xsize; x++) { \
|
for (x = 0; x < out->xsize; x++) { \
|
||||||
*p0 = op(type, *p1); \
|
*p0 = op(type, *p1); \
|
||||||
p0++; p1++;\
|
p0++; \
|
||||||
|
p1++; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BINOP(name, op, type) \
|
#define BINOP(name, op, type) \
|
||||||
void name(Imaging out, Imaging im1, Imaging im2)\
|
void name(Imaging out, Imaging im1, Imaging im2) { \
|
||||||
{\
|
|
||||||
int x, y; \
|
int x, y; \
|
||||||
for (y = 0; y < out->ysize; y++) { \
|
for (y = 0; y < out->ysize; y++) { \
|
||||||
type *p0 = (type *)out->image[y]; \
|
type *p0 = (type *)out->image[y]; \
|
||||||
|
@ -47,7 +46,9 @@ void name(Imaging out, Imaging im1, Imaging im2)\
|
||||||
type *p2 = (type *)im2->image[y]; \
|
type *p2 = (type *)im2->image[y]; \
|
||||||
for (x = 0; x < out->xsize; x++) { \
|
for (x = 0; x < out->xsize; x++) { \
|
||||||
*p0 = op(type, *p1, *p2); \
|
*p0 = op(type, *p1, *p2); \
|
||||||
p0++; p1++; p2++;\
|
p0++; \
|
||||||
|
p1++; \
|
||||||
|
p2++; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -85,8 +86,8 @@ void name(Imaging out, Imaging im1, Imaging im2)\
|
||||||
#define MOD_I(type, v1, v2) ((v2) != 0) ? (v1) % (v2) : 0
|
#define MOD_I(type, v1, v2) ((v2) != 0) ? (v1) % (v2) : 0
|
||||||
#define MOD_F(type, v1, v2) ((v2) != 0.0F) ? fmod((v1), (v2)) : 0.0F
|
#define MOD_F(type, v1, v2) ((v2) != 0.0F) ? fmod((v1), (v2)) : 0.0F
|
||||||
|
|
||||||
static int powi(int x, int y)
|
static int
|
||||||
{
|
powi(int x, int y) {
|
||||||
double v = pow(x, y) + 0.5;
|
double v = pow(x, y) + 0.5;
|
||||||
if (errno == EDOM) {
|
if (errno == EDOM) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -162,8 +163,7 @@ BINOP(gt_F, GT, FLOAT32)
|
||||||
BINOP(ge_F, GE, FLOAT32)
|
BINOP(ge_F, GE, FLOAT32)
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_unop(PyObject* self, PyObject* args)
|
_unop(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
Imaging out;
|
Imaging out;
|
||||||
Imaging im1;
|
Imaging im1;
|
||||||
void (*unop)(Imaging, Imaging);
|
void (*unop)(Imaging, Imaging);
|
||||||
|
@ -185,8 +185,7 @@ _unop(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_binop(PyObject* self, PyObject* args)
|
_binop(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
Imaging out;
|
Imaging out;
|
||||||
Imaging im1;
|
Imaging im1;
|
||||||
Imaging im2;
|
Imaging im2;
|
||||||
|
@ -210,14 +209,10 @@ _binop(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef _functions[] = {
|
static PyMethodDef _functions[] = {
|
||||||
{"unop", _unop, 1},
|
{"unop", _unop, 1}, {"binop", _binop, 1}, {NULL, NULL}};
|
||||||
{"binop", _binop, 1},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
install(PyObject *d, char* name, void* value)
|
install(PyObject *d, char *name, void *value) {
|
||||||
{
|
|
||||||
PyObject *v = PyLong_FromSsize_t((Py_ssize_t)value);
|
PyObject *v = PyLong_FromSsize_t((Py_ssize_t)value);
|
||||||
if (!v || PyDict_SetItemString(d, name, v)) {
|
if (!v || PyDict_SetItemString(d, name, v)) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
Returns number of changed pixels.
|
Returns number of changed pixels.
|
||||||
*/
|
*/
|
||||||
static PyObject *
|
static PyObject *
|
||||||
apply(PyObject *self, PyObject* args)
|
apply(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
const char *lut;
|
const char *lut;
|
||||||
PyObject *py_lut;
|
PyObject *py_lut;
|
||||||
Py_ssize_t lut_len, i0, i1;
|
Py_ssize_t lut_len, i0, i1;
|
||||||
|
@ -63,13 +62,11 @@ apply(PyObject *self, PyObject* args)
|
||||||
width = imgin->xsize;
|
width = imgin->xsize;
|
||||||
height = imgin->ysize;
|
height = imgin->ysize;
|
||||||
|
|
||||||
if (imgin->type != IMAGING_TYPE_UINT8 ||
|
if (imgin->type != IMAGING_TYPE_UINT8 || imgin->bands != 1) {
|
||||||
imgin->bands != 1) {
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Unsupported image type");
|
PyErr_SetString(PyExc_RuntimeError, "Unsupported image type");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (imgout->type != IMAGING_TYPE_UINT8 ||
|
if (imgout->type != IMAGING_TYPE_UINT8 || imgout->bands != 1) {
|
||||||
imgout->bands != 1) {
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Unsupported image type");
|
PyErr_SetString(PyExc_RuntimeError, "Unsupported image type");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -109,15 +106,9 @@ apply(PyObject *self, PyObject* args)
|
||||||
unsigned char b7 = nrow[col_idx] & 1;
|
unsigned char b7 = nrow[col_idx] & 1;
|
||||||
unsigned char b8 = nrow[cip] & 1;
|
unsigned char b8 = nrow[cip] & 1;
|
||||||
|
|
||||||
int lut_idx = (b0
|
int lut_idx =
|
||||||
|(b1 << 1)
|
(b0 | (b1 << 1) | (b2 << 2) | (b3 << 3) | (b4 << 4) | (b5 << 5) |
|
||||||
|(b2 << 2)
|
(b6 << 6) | (b7 << 7) | (b8 << 8));
|
||||||
|(b3 << 3)
|
|
||||||
|(b4 << 4)
|
|
||||||
|(b5 << 5)
|
|
||||||
|(b6 << 6)
|
|
||||||
|(b7 << 7)
|
|
||||||
|(b8 << 8));
|
|
||||||
outrow[col_idx] = 255 * (lut[lut_idx] & 1);
|
outrow[col_idx] = 255 * (lut[lut_idx] & 1);
|
||||||
num_changed_pixels += ((b4 & 1) != (outrow[col_idx] & 1));
|
num_changed_pixels += ((b4 & 1) != (outrow[col_idx] & 1));
|
||||||
}
|
}
|
||||||
|
@ -136,8 +127,7 @@ apply(PyObject *self, PyObject* args)
|
||||||
Returns list of matching pixels.
|
Returns list of matching pixels.
|
||||||
*/
|
*/
|
||||||
static PyObject *
|
static PyObject *
|
||||||
match(PyObject *self, PyObject* args)
|
match(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
const char *lut;
|
const char *lut;
|
||||||
PyObject *py_lut;
|
PyObject *py_lut;
|
||||||
Py_ssize_t lut_len, i0;
|
Py_ssize_t lut_len, i0;
|
||||||
|
@ -167,8 +157,7 @@ match(PyObject *self, PyObject* args)
|
||||||
lut = PyBytes_AsString(py_lut);
|
lut = PyBytes_AsString(py_lut);
|
||||||
imgin = (Imaging)i0;
|
imgin = (Imaging)i0;
|
||||||
|
|
||||||
if (imgin->type != IMAGING_TYPE_UINT8 ||
|
if (imgin->type != IMAGING_TYPE_UINT8 || imgin->bands != 1) {
|
||||||
imgin->bands != 1) {
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Unsupported image type");
|
PyErr_SetString(PyExc_RuntimeError, "Unsupported image type");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -199,15 +188,9 @@ match(PyObject *self, PyObject* args)
|
||||||
unsigned char b7 = nrow[col_idx] & 1;
|
unsigned char b7 = nrow[col_idx] & 1;
|
||||||
unsigned char b8 = nrow[cip] & 1;
|
unsigned char b8 = nrow[cip] & 1;
|
||||||
|
|
||||||
int lut_idx = (b0
|
int lut_idx =
|
||||||
|(b1 << 1)
|
(b0 | (b1 << 1) | (b2 << 2) | (b3 << 3) | (b4 << 4) | (b5 << 5) |
|
||||||
|(b2 << 2)
|
(b6 << 6) | (b7 << 7) | (b8 << 8));
|
||||||
|(b3 << 3)
|
|
||||||
|(b4 << 4)
|
|
||||||
|(b5 << 5)
|
|
||||||
|(b6 << 6)
|
|
||||||
|(b7 << 7)
|
|
||||||
|(b8 << 8));
|
|
||||||
if (lut[lut_idx]) {
|
if (lut[lut_idx]) {
|
||||||
PyObject *coordObj = Py_BuildValue("(nn)", col_idx, row_idx);
|
PyObject *coordObj = Py_BuildValue("(nn)", col_idx, row_idx);
|
||||||
PyList_Append(ret, coordObj);
|
PyList_Append(ret, coordObj);
|
||||||
|
@ -223,8 +206,7 @@ match(PyObject *self, PyObject* args)
|
||||||
This is faster than match as only 1x1 lookup is made.
|
This is faster than match as only 1x1 lookup is made.
|
||||||
*/
|
*/
|
||||||
static PyObject *
|
static PyObject *
|
||||||
get_on_pixels(PyObject *self, PyObject* args)
|
get_on_pixels(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
Py_ssize_t i0;
|
Py_ssize_t i0;
|
||||||
Imaging img;
|
Imaging img;
|
||||||
UINT8 **rows;
|
UINT8 **rows;
|
||||||
|
@ -254,10 +236,8 @@ get_on_pixels(PyObject *self, PyObject* args)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setup_module(PyObject* m)
|
setup_module(PyObject *m) {
|
||||||
{
|
|
||||||
PyObject *d = PyModule_GetDict(m);
|
PyObject *d = PyModule_GetDict(m);
|
||||||
|
|
||||||
PyDict_SetItemString(d, "__version", PyUnicode_FromString("0.1"));
|
PyDict_SetItemString(d, "__version", PyUnicode_FromString("0.1"));
|
||||||
|
@ -270,8 +250,7 @@ static PyMethodDef functions[] = {
|
||||||
{"apply", (PyCFunction)apply, METH_VARARGS, NULL},
|
{"apply", (PyCFunction)apply, METH_VARARGS, NULL},
|
||||||
{"get_on_pixels", (PyCFunction)get_on_pixels, METH_VARARGS, NULL},
|
{"get_on_pixels", (PyCFunction)get_on_pixels, METH_VARARGS, NULL},
|
||||||
{"match", (PyCFunction)match, METH_VARARGS, NULL},
|
{"match", (PyCFunction)match, METH_VARARGS, NULL},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}};
|
||||||
};
|
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
PyInit__imagingmorph(void) {
|
PyInit__imagingmorph(void) {
|
||||||
|
|
|
@ -12,28 +12,27 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "libImaging/Imaging.h"
|
#include "libImaging/Imaging.h"
|
||||||
|
|
||||||
#include "Tk/_tkmini.h"
|
#include "Tk/_tkmini.h"
|
||||||
|
|
||||||
/* must link with Tk/tkImaging.c */
|
/* must link with Tk/tkImaging.c */
|
||||||
extern void TkImaging_Init(Tcl_Interp* interp);
|
extern void
|
||||||
extern int load_tkinter_funcs(void);
|
TkImaging_Init(Tcl_Interp *interp);
|
||||||
|
extern int
|
||||||
|
load_tkinter_funcs(void);
|
||||||
|
|
||||||
/* copied from _tkinter.c (this isn't as bad as it may seem: for new
|
/* copied from _tkinter.c (this isn't as bad as it may seem: for new
|
||||||
versions, we use _tkinter's interpaddr hook instead, and all older
|
versions, we use _tkinter's interpaddr hook instead, and all older
|
||||||
versions use this structure layout) */
|
versions use this structure layout) */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD Tcl_Interp *interp;
|
||||||
Tcl_Interp* interp;
|
|
||||||
} TkappObject;
|
} TkappObject;
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_tkinit(PyObject* self, PyObject* args)
|
_tkinit(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
Tcl_Interp *interp;
|
Tcl_Interp *interp;
|
||||||
|
|
||||||
PyObject *arg;
|
PyObject *arg;
|
||||||
|
|
237
src/_webp.c
237
src/_webp.c
|
@ -21,11 +21,13 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ImagingSectionEnter(ImagingSectionCookie* cookie) {
|
void
|
||||||
|
ImagingSectionEnter(ImagingSectionCookie *cookie) {
|
||||||
*cookie = (PyThreadState *)PyEval_SaveThread();
|
*cookie = (PyThreadState *)PyEval_SaveThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImagingSectionLeave(ImagingSectionCookie* cookie) {
|
void
|
||||||
|
ImagingSectionLeave(ImagingSectionCookie *cookie) {
|
||||||
PyEval_RestoreThread((PyThreadState *)*cookie);
|
PyEval_RestoreThread((PyThreadState *)*cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +38,14 @@ void ImagingSectionLeave(ImagingSectionCookie* cookie) {
|
||||||
#ifdef HAVE_WEBPMUX
|
#ifdef HAVE_WEBPMUX
|
||||||
|
|
||||||
static const char *const kErrorMessages[-WEBP_MUX_NOT_ENOUGH_DATA + 1] = {
|
static const char *const kErrorMessages[-WEBP_MUX_NOT_ENOUGH_DATA + 1] = {
|
||||||
"WEBP_MUX_NOT_FOUND", "WEBP_MUX_INVALID_ARGUMENT", "WEBP_MUX_BAD_DATA",
|
"WEBP_MUX_NOT_FOUND",
|
||||||
"WEBP_MUX_MEMORY_ERROR", "WEBP_MUX_NOT_ENOUGH_DATA"
|
"WEBP_MUX_INVALID_ARGUMENT",
|
||||||
};
|
"WEBP_MUX_BAD_DATA",
|
||||||
|
"WEBP_MUX_MEMORY_ERROR",
|
||||||
|
"WEBP_MUX_NOT_ENOUGH_DATA"};
|
||||||
|
|
||||||
PyObject* HandleMuxError(WebPMuxError err, char* chunk) {
|
PyObject *
|
||||||
|
HandleMuxError(WebPMuxError err, char *chunk) {
|
||||||
char message[100];
|
char message[100];
|
||||||
int message_len;
|
int message_len;
|
||||||
assert(err <= WEBP_MUX_NOT_FOUND && err >= WEBP_MUX_NOT_ENOUGH_DATA);
|
assert(err <= WEBP_MUX_NOT_FOUND && err >= WEBP_MUX_NOT_ENOUGH_DATA);
|
||||||
|
@ -52,9 +57,11 @@ PyObject* HandleMuxError(WebPMuxError err, char* chunk) {
|
||||||
|
|
||||||
// Create the error message
|
// Create the error message
|
||||||
if (chunk == NULL) {
|
if (chunk == NULL) {
|
||||||
message_len = sprintf(message, "could not assemble chunks: %s", kErrorMessages[-err]);
|
message_len =
|
||||||
|
sprintf(message, "could not assemble chunks: %s", kErrorMessages[-err]);
|
||||||
} else {
|
} else {
|
||||||
message_len = sprintf(message, "could not set %.4s chunk: %s", chunk, kErrorMessages[-err]);
|
message_len = sprintf(
|
||||||
|
message, "could not set %.4s chunk: %s", chunk, kErrorMessages[-err]);
|
||||||
}
|
}
|
||||||
if (message_len < 0) {
|
if (message_len < 0) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "failed to construct error message");
|
PyErr_SetString(PyExc_RuntimeError, "failed to construct error message");
|
||||||
|
@ -90,8 +97,7 @@ PyObject* HandleMuxError(WebPMuxError err, char* chunk) {
|
||||||
|
|
||||||
// Encoder type
|
// Encoder type
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD WebPAnimEncoder *enc;
|
||||||
WebPAnimEncoder* enc;
|
|
||||||
WebPPicture frame;
|
WebPPicture frame;
|
||||||
} WebPAnimEncoderObject;
|
} WebPAnimEncoderObject;
|
||||||
|
|
||||||
|
@ -99,8 +105,7 @@ static PyTypeObject WebPAnimEncoder_Type;
|
||||||
|
|
||||||
// Decoder type
|
// Decoder type
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD WebPAnimDecoder *dec;
|
||||||
WebPAnimDecoder* dec;
|
|
||||||
WebPAnimInfo info;
|
WebPAnimInfo info;
|
||||||
WebPData data;
|
WebPData data;
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -109,8 +114,8 @@ typedef struct {
|
||||||
static PyTypeObject WebPAnimDecoder_Type;
|
static PyTypeObject WebPAnimDecoder_Type;
|
||||||
|
|
||||||
// Encoder functions
|
// Encoder functions
|
||||||
PyObject* _anim_encoder_new(PyObject* self, PyObject* args)
|
PyObject *
|
||||||
{
|
_anim_encoder_new(PyObject *self, PyObject *args) {
|
||||||
int width, height;
|
int width, height;
|
||||||
uint32_t bgcolor;
|
uint32_t bgcolor;
|
||||||
int loop_count;
|
int loop_count;
|
||||||
|
@ -122,9 +127,18 @@ PyObject* _anim_encoder_new(PyObject* self, PyObject* args)
|
||||||
WebPAnimEncoderObject *encp = NULL;
|
WebPAnimEncoderObject *encp = NULL;
|
||||||
WebPAnimEncoder *enc = NULL;
|
WebPAnimEncoder *enc = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "iiIiiiiii",
|
if (!PyArg_ParseTuple(
|
||||||
&width, &height, &bgcolor, &loop_count, &minimize_size,
|
args,
|
||||||
&kmin, &kmax, &allow_mixed, &verbose)) {
|
"iiIiiiiii",
|
||||||
|
&width,
|
||||||
|
&height,
|
||||||
|
&bgcolor,
|
||||||
|
&loop_count,
|
||||||
|
&minimize_size,
|
||||||
|
&kmin,
|
||||||
|
&kmax,
|
||||||
|
&allow_mixed,
|
||||||
|
&verbose)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,16 +178,16 @@ PyObject* _anim_encoder_new(PyObject* self, PyObject* args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _anim_encoder_dealloc(PyObject* self)
|
PyObject *
|
||||||
{
|
_anim_encoder_dealloc(PyObject *self) {
|
||||||
WebPAnimEncoderObject *encp = (WebPAnimEncoderObject *)self;
|
WebPAnimEncoderObject *encp = (WebPAnimEncoderObject *)self;
|
||||||
WebPPictureFree(&(encp->frame));
|
WebPPictureFree(&(encp->frame));
|
||||||
WebPAnimEncoderDelete(encp->enc);
|
WebPAnimEncoderDelete(encp->enc);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _anim_encoder_add(PyObject* self, PyObject* args)
|
PyObject *
|
||||||
{
|
_anim_encoder_add(PyObject *self, PyObject *args) {
|
||||||
uint8_t *rgb;
|
uint8_t *rgb;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
int timestamp;
|
int timestamp;
|
||||||
|
@ -188,9 +202,18 @@ PyObject* _anim_encoder_add(PyObject* self, PyObject* args)
|
||||||
WebPAnimEncoder *enc = encp->enc;
|
WebPAnimEncoder *enc = encp->enc;
|
||||||
WebPPicture *frame = &(encp->frame);
|
WebPPicture *frame = &(encp->frame);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "z#iiisifi",
|
if (!PyArg_ParseTuple(
|
||||||
(char**)&rgb, &size, ×tamp, &width, &height, &mode,
|
args,
|
||||||
&lossless, &quality_factor, &method)) {
|
"z#iiisifi",
|
||||||
|
(char **)&rgb,
|
||||||
|
&size,
|
||||||
|
×tamp,
|
||||||
|
&width,
|
||||||
|
&height,
|
||||||
|
&mode,
|
||||||
|
&lossless,
|
||||||
|
&quality_factor,
|
||||||
|
&method)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,8 +259,8 @@ PyObject* _anim_encoder_add(PyObject* self, PyObject* args)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _anim_encoder_assemble(PyObject* self, PyObject* args)
|
PyObject *
|
||||||
{
|
_anim_encoder_assemble(PyObject *self, PyObject *args) {
|
||||||
uint8_t *icc_bytes;
|
uint8_t *icc_bytes;
|
||||||
uint8_t *exif_bytes;
|
uint8_t *exif_bytes;
|
||||||
uint8_t *xmp_bytes;
|
uint8_t *xmp_bytes;
|
||||||
|
@ -250,8 +273,15 @@ PyObject* _anim_encoder_assemble(PyObject* self, PyObject* args)
|
||||||
WebPMux *mux = NULL;
|
WebPMux *mux = NULL;
|
||||||
PyObject *ret = NULL;
|
PyObject *ret = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#s#s#",
|
if (!PyArg_ParseTuple(
|
||||||
&icc_bytes, &icc_size, &exif_bytes, &exif_size, &xmp_bytes, &xmp_size)) {
|
args,
|
||||||
|
"s#s#s#",
|
||||||
|
&icc_bytes,
|
||||||
|
&icc_size,
|
||||||
|
&exif_bytes,
|
||||||
|
&exif_size,
|
||||||
|
&xmp_bytes,
|
||||||
|
&xmp_size)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,8 +354,8 @@ PyObject* _anim_encoder_assemble(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decoder functions
|
// Decoder functions
|
||||||
PyObject* _anim_decoder_new(PyObject* self, PyObject* args)
|
PyObject *
|
||||||
{
|
_anim_decoder_new(PyObject *self, PyObject *args) {
|
||||||
PyBytesObject *webp_string;
|
PyBytesObject *webp_string;
|
||||||
const uint8_t *webp;
|
const uint8_t *webp;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
|
@ -369,30 +399,31 @@ PyObject* _anim_decoder_new(PyObject* self, PyObject* args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _anim_decoder_dealloc(PyObject* self)
|
PyObject *
|
||||||
{
|
_anim_decoder_dealloc(PyObject *self) {
|
||||||
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
|
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
|
||||||
WebPDataClear(&(decp->data));
|
WebPDataClear(&(decp->data));
|
||||||
WebPAnimDecoderDelete(decp->dec);
|
WebPAnimDecoderDelete(decp->dec);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _anim_decoder_get_info(PyObject* self)
|
PyObject *
|
||||||
{
|
_anim_decoder_get_info(PyObject *self) {
|
||||||
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
|
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
|
||||||
WebPAnimInfo *info = &(decp->info);
|
WebPAnimInfo *info = &(decp->info);
|
||||||
|
|
||||||
return Py_BuildValue("IIIIIs",
|
return Py_BuildValue(
|
||||||
info->canvas_width, info->canvas_height,
|
"IIIIIs",
|
||||||
|
info->canvas_width,
|
||||||
|
info->canvas_height,
|
||||||
info->loop_count,
|
info->loop_count,
|
||||||
info->bgcolor,
|
info->bgcolor,
|
||||||
info->frame_count,
|
info->frame_count,
|
||||||
decp->mode
|
decp->mode);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _anim_decoder_get_chunk(PyObject* self, PyObject* args)
|
PyObject *
|
||||||
{
|
_anim_decoder_get_chunk(PyObject *self, PyObject *args) {
|
||||||
char *mode;
|
char *mode;
|
||||||
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
|
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
|
||||||
const WebPDemuxer *demux;
|
const WebPDemuxer *demux;
|
||||||
|
@ -414,8 +445,8 @@ PyObject* _anim_decoder_get_chunk(PyObject* self, PyObject* args)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _anim_decoder_get_next(PyObject* self)
|
PyObject *
|
||||||
{
|
_anim_decoder_get_next(PyObject *self) {
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
int timestamp;
|
int timestamp;
|
||||||
PyObject *bytes;
|
PyObject *bytes;
|
||||||
|
@ -427,8 +458,8 @@ PyObject* _anim_decoder_get_next(PyObject* self)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = PyBytes_FromStringAndSize((char *)buf,
|
bytes = PyBytes_FromStringAndSize(
|
||||||
decp->info.canvas_width * 4 * decp->info.canvas_height);
|
(char *)buf, decp->info.canvas_width * 4 * decp->info.canvas_height);
|
||||||
|
|
||||||
ret = Py_BuildValue("Si", bytes, timestamp);
|
ret = Py_BuildValue("Si", bytes, timestamp);
|
||||||
|
|
||||||
|
@ -436,8 +467,8 @@ PyObject* _anim_decoder_get_next(PyObject* self)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _anim_decoder_reset(PyObject* self)
|
PyObject *
|
||||||
{
|
_anim_decoder_reset(PyObject *self) {
|
||||||
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
|
WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
|
||||||
WebPAnimDecoderReset(decp->dec);
|
WebPAnimDecoderReset(decp->dec);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -456,8 +487,7 @@ static struct PyMethodDef _anim_encoder_methods[] = {
|
||||||
|
|
||||||
// WebPAnimDecoder type definition
|
// WebPAnimDecoder type definition
|
||||||
static PyTypeObject WebPAnimEncoder_Type = {
|
static PyTypeObject WebPAnimEncoder_Type = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "WebPAnimEncoder", /*tp_name */
|
||||||
"WebPAnimEncoder", /*tp_name */
|
|
||||||
sizeof(WebPAnimEncoderObject), /*tp_size */
|
sizeof(WebPAnimEncoderObject), /*tp_size */
|
||||||
0, /*tp_itemsize */
|
0, /*tp_itemsize */
|
||||||
/* methods */
|
/* methods */
|
||||||
|
@ -500,8 +530,7 @@ static struct PyMethodDef _anim_decoder_methods[] = {
|
||||||
|
|
||||||
// WebPAnimDecoder type definition
|
// WebPAnimDecoder type definition
|
||||||
static PyTypeObject WebPAnimDecoder_Type = {
|
static PyTypeObject WebPAnimDecoder_Type = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "WebPAnimDecoder", /*tp_name */
|
||||||
"WebPAnimDecoder", /*tp_name */
|
|
||||||
sizeof(WebPAnimDecoderObject), /*tp_size */
|
sizeof(WebPAnimDecoderObject), /*tp_size */
|
||||||
0, /*tp_itemsize */
|
0, /*tp_itemsize */
|
||||||
/* methods */
|
/* methods */
|
||||||
|
@ -539,8 +568,8 @@ static PyTypeObject WebPAnimDecoder_Type = {
|
||||||
/* Legacy WebP Support */
|
/* Legacy WebP Support */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
|
PyObject *
|
||||||
{
|
WebPEncode_wrapper(PyObject *self, PyObject *args) {
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int lossless;
|
int lossless;
|
||||||
|
@ -565,9 +594,23 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
|
||||||
WebPMemoryWriter writer;
|
WebPMemoryWriter writer;
|
||||||
WebPPicture pic;
|
WebPPicture pic;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "y#iiifss#is#s#",
|
if (!PyArg_ParseTuple(
|
||||||
(char**)&rgb, &size, &width, &height, &lossless, &quality_factor, &mode,
|
args,
|
||||||
&icc_bytes, &icc_size, &method, &exif_bytes, &exif_size, &xmp_bytes, &xmp_size)) {
|
"y#iiifss#is#s#",
|
||||||
|
(char **)&rgb,
|
||||||
|
&size,
|
||||||
|
&width,
|
||||||
|
&height,
|
||||||
|
&lossless,
|
||||||
|
&quality_factor,
|
||||||
|
&mode,
|
||||||
|
&icc_bytes,
|
||||||
|
&icc_size,
|
||||||
|
&method,
|
||||||
|
&exif_bytes,
|
||||||
|
&exif_size,
|
||||||
|
&xmp_bytes,
|
||||||
|
&xmp_size)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,7 +745,8 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
ret_size = output_data.size;
|
ret_size = output_data.size;
|
||||||
if (ret_size > 0) {
|
if (ret_size > 0) {
|
||||||
PyObject *ret = PyBytes_FromStringAndSize((char*)output_data.bytes, ret_size);
|
PyObject *ret =
|
||||||
|
PyBytes_FromStringAndSize((char *)output_data.bytes, ret_size);
|
||||||
WebPDataClear(&output_data);
|
WebPDataClear(&output_data);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -711,12 +755,13 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* WebPDecode_wrapper(PyObject* self, PyObject* args)
|
PyObject *
|
||||||
{
|
WebPDecode_wrapper(PyObject *self, PyObject *args) {
|
||||||
PyBytesObject *webp_string;
|
PyBytesObject *webp_string;
|
||||||
const uint8_t *webp;
|
const uint8_t *webp;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
PyObject *ret = Py_None, *bytes = NULL, *pymode = NULL, *icc_profile = NULL, *exif = NULL;
|
PyObject *ret = Py_None, *bytes = NULL, *pymode = NULL, *icc_profile = NULL,
|
||||||
|
*exif = NULL;
|
||||||
WebPDecoderConfig config;
|
WebPDecoderConfig config;
|
||||||
VP8StatusCode vp8_status_code = VP8_STATUS_OK;
|
VP8StatusCode vp8_status_code = VP8_STATUS_OK;
|
||||||
char *mode = "RGB";
|
char *mode = "RGB";
|
||||||
|
@ -755,8 +800,7 @@ PyObject* WebPDecode_wrapper(PyObject* self, PyObject* args)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WEBP_MUX_OK != WebPMuxGetFrame(mux, 1, &image))
|
if (WEBP_MUX_OK != WebPMuxGetFrame(mux, 1, &image)) {
|
||||||
{
|
|
||||||
WebPMuxDelete(mux);
|
WebPMuxDelete(mux);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -767,11 +811,13 @@ PyObject* WebPDecode_wrapper(PyObject* self, PyObject* args)
|
||||||
vp8_status_code = WebPDecode(webp, size, &config);
|
vp8_status_code = WebPDecode(webp, size, &config);
|
||||||
|
|
||||||
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "ICCP", &icc_profile_data)) {
|
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "ICCP", &icc_profile_data)) {
|
||||||
icc_profile = PyBytes_FromStringAndSize((const char*)icc_profile_data.bytes, icc_profile_data.size);
|
icc_profile = PyBytes_FromStringAndSize(
|
||||||
|
(const char *)icc_profile_data.bytes, icc_profile_data.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "EXIF", &exif_data)) {
|
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "EXIF", &exif_data)) {
|
||||||
exif = PyBytes_FromStringAndSize((const char*)exif_data.bytes, exif_data.size);
|
exif = PyBytes_FromStringAndSize(
|
||||||
|
(const char *)exif_data.bytes, exif_data.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPDataClear(&image.bitstream);
|
WebPDataClear(&image.bitstream);
|
||||||
|
@ -785,18 +831,22 @@ PyObject* WebPDecode_wrapper(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.output.colorspace < MODE_YUV) {
|
if (config.output.colorspace < MODE_YUV) {
|
||||||
bytes = PyBytes_FromStringAndSize((char*)config.output.u.RGBA.rgba,
|
bytes = PyBytes_FromStringAndSize(
|
||||||
config.output.u.RGBA.size);
|
(char *)config.output.u.RGBA.rgba, config.output.u.RGBA.size);
|
||||||
} else {
|
} else {
|
||||||
// Skipping YUV for now. Need Test Images.
|
// Skipping YUV for now. Need Test Images.
|
||||||
// UNDONE -- unclear if we'll ever get here if we set mode_rgb*
|
// UNDONE -- unclear if we'll ever get here if we set mode_rgb*
|
||||||
bytes = PyBytes_FromStringAndSize((char*)config.output.u.YUVA.y,
|
bytes = PyBytes_FromStringAndSize(
|
||||||
config.output.u.YUVA.y_size);
|
(char *)config.output.u.YUVA.y, config.output.u.YUVA.y_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pymode = PyUnicode_FromString(mode);
|
pymode = PyUnicode_FromString(mode);
|
||||||
ret = Py_BuildValue("SiiSSS", bytes, config.output.width,
|
ret = Py_BuildValue(
|
||||||
config.output.height, pymode,
|
"SiiSSS",
|
||||||
|
bytes,
|
||||||
|
config.output.width,
|
||||||
|
config.output.height,
|
||||||
|
pymode,
|
||||||
NULL == icc_profile ? Py_None : icc_profile,
|
NULL == icc_profile ? Py_None : icc_profile,
|
||||||
NULL == exif ? Py_None : exif);
|
NULL == exif ? Py_None : exif);
|
||||||
|
|
||||||
|
@ -817,17 +867,22 @@ end:
|
||||||
|
|
||||||
// Return the decoder's version number, packed in hexadecimal using 8bits for
|
// Return the decoder's version number, packed in hexadecimal using 8bits for
|
||||||
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||||
PyObject* WebPDecoderVersion_wrapper() {
|
PyObject *
|
||||||
|
WebPDecoderVersion_wrapper() {
|
||||||
return Py_BuildValue("i", WebPGetDecoderVersion());
|
return Py_BuildValue("i", WebPGetDecoderVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version as string
|
// Version as string
|
||||||
const char *
|
const char *
|
||||||
WebPDecoderVersion_str(void)
|
WebPDecoderVersion_str(void) {
|
||||||
{
|
|
||||||
static char version[20];
|
static char version[20];
|
||||||
int version_number = WebPGetDecoderVersion();
|
int version_number = WebPGetDecoderVersion();
|
||||||
sprintf(version, "%d.%d.%d", version_number >> 16, (version_number >> 8) % 0x100, version_number % 0x100);
|
sprintf(
|
||||||
|
version,
|
||||||
|
"%d.%d.%d",
|
||||||
|
version_number >> 16,
|
||||||
|
(version_number >> 8) % 0x100,
|
||||||
|
version_number % 0x100);
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,11 +890,13 @@ WebPDecoderVersion_str(void)
|
||||||
* The version of webp that ships with (0.1.3) Ubuntu 12.04 doesn't handle alpha well.
|
* The version of webp that ships with (0.1.3) Ubuntu 12.04 doesn't handle alpha well.
|
||||||
* Files that are valid with 0.3 are reported as being invalid.
|
* Files that are valid with 0.3 are reported as being invalid.
|
||||||
*/
|
*/
|
||||||
int WebPDecoderBuggyAlpha(void) {
|
int
|
||||||
|
WebPDecoderBuggyAlpha(void) {
|
||||||
return WebPGetDecoderVersion() == 0x0103;
|
return WebPGetDecoderVersion() == 0x0103;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* WebPDecoderBuggyAlpha_wrapper() {
|
PyObject *
|
||||||
|
WebPDecoderBuggyAlpha_wrapper() {
|
||||||
return Py_BuildValue("i", WebPDecoderBuggyAlpha());
|
return Py_BuildValue("i", WebPDecoderBuggyAlpha());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -847,8 +904,7 @@ PyObject* WebPDecoderBuggyAlpha_wrapper() {
|
||||||
/* Module Setup */
|
/* Module Setup */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
static PyMethodDef webpMethods[] =
|
static PyMethodDef webpMethods[] = {
|
||||||
{
|
|
||||||
#ifdef HAVE_WEBPANIM
|
#ifdef HAVE_WEBPANIM
|
||||||
{"WebPAnimDecoder", _anim_decoder_new, METH_VARARGS, "WebPAnimDecoder"},
|
{"WebPAnimDecoder", _anim_decoder_new, METH_VARARGS, "WebPAnimDecoder"},
|
||||||
{"WebPAnimEncoder", _anim_encoder_new, METH_VARARGS, "WebPAnimEncoder"},
|
{"WebPAnimEncoder", _anim_encoder_new, METH_VARARGS, "WebPAnimEncoder"},
|
||||||
|
@ -856,11 +912,14 @@ static PyMethodDef webpMethods[] =
|
||||||
{"WebPEncode", WebPEncode_wrapper, METH_VARARGS, "WebPEncode"},
|
{"WebPEncode", WebPEncode_wrapper, METH_VARARGS, "WebPEncode"},
|
||||||
{"WebPDecode", WebPDecode_wrapper, METH_VARARGS, "WebPDecode"},
|
{"WebPDecode", WebPDecode_wrapper, METH_VARARGS, "WebPDecode"},
|
||||||
{"WebPDecoderVersion", WebPDecoderVersion_wrapper, METH_NOARGS, "WebPVersion"},
|
{"WebPDecoderVersion", WebPDecoderVersion_wrapper, METH_NOARGS, "WebPVersion"},
|
||||||
{"WebPDecoderBuggyAlpha", WebPDecoderBuggyAlpha_wrapper, METH_NOARGS, "WebPDecoderBuggyAlpha"},
|
{"WebPDecoderBuggyAlpha",
|
||||||
{NULL, NULL}
|
WebPDecoderBuggyAlpha_wrapper,
|
||||||
};
|
METH_NOARGS,
|
||||||
|
"WebPDecoderBuggyAlpha"},
|
||||||
|
{NULL, NULL}};
|
||||||
|
|
||||||
void addMuxFlagToModule(PyObject* m) {
|
void
|
||||||
|
addMuxFlagToModule(PyObject *m) {
|
||||||
#ifdef HAVE_WEBPMUX
|
#ifdef HAVE_WEBPMUX
|
||||||
PyModule_AddObject(m, "HAVE_WEBPMUX", Py_True);
|
PyModule_AddObject(m, "HAVE_WEBPMUX", Py_True);
|
||||||
#else
|
#else
|
||||||
|
@ -868,7 +927,8 @@ void addMuxFlagToModule(PyObject* m) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void addAnimFlagToModule(PyObject* m) {
|
void
|
||||||
|
addAnimFlagToModule(PyObject *m) {
|
||||||
#ifdef HAVE_WEBPANIM
|
#ifdef HAVE_WEBPANIM
|
||||||
PyModule_AddObject(m, "HAVE_WEBPANIM", Py_True);
|
PyModule_AddObject(m, "HAVE_WEBPANIM", Py_True);
|
||||||
#else
|
#else
|
||||||
|
@ -876,18 +936,21 @@ void addAnimFlagToModule(PyObject* m) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTransparencyFlagToModule(PyObject* m) {
|
void
|
||||||
PyModule_AddObject(m, "HAVE_TRANSPARENCY",
|
addTransparencyFlagToModule(PyObject *m) {
|
||||||
PyBool_FromLong(!WebPDecoderBuggyAlpha()));
|
PyModule_AddObject(
|
||||||
|
m, "HAVE_TRANSPARENCY", PyBool_FromLong(!WebPDecoderBuggyAlpha()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_module(PyObject* m) {
|
static int
|
||||||
|
setup_module(PyObject *m) {
|
||||||
PyObject *d = PyModule_GetDict(m);
|
PyObject *d = PyModule_GetDict(m);
|
||||||
addMuxFlagToModule(m);
|
addMuxFlagToModule(m);
|
||||||
addAnimFlagToModule(m);
|
addAnimFlagToModule(m);
|
||||||
addTransparencyFlagToModule(m);
|
addTransparencyFlagToModule(m);
|
||||||
|
|
||||||
PyDict_SetItemString(d, "webpdecoder_version", PyUnicode_FromString(WebPDecoderVersion_str()));
|
PyDict_SetItemString(
|
||||||
|
d, "webpdecoder_version", PyUnicode_FromString(WebPDecoderVersion_str()));
|
||||||
|
|
||||||
#ifdef HAVE_WEBPANIM
|
#ifdef HAVE_WEBPANIM
|
||||||
/* Ready object types */
|
/* Ready object types */
|
||||||
|
|
137
src/decode.c
137
src/decode.c
|
@ -39,15 +39,13 @@
|
||||||
#include "libImaging/Bit.h"
|
#include "libImaging/Bit.h"
|
||||||
#include "libImaging/Sgi.h"
|
#include "libImaging/Sgi.h"
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Common */
|
/* Common */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD int (*decode)(
|
||||||
int (*decode)(Imaging im, ImagingCodecState state,
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
|
||||||
int (*cleanup)(ImagingCodecState state);
|
int (*cleanup)(ImagingCodecState state);
|
||||||
struct ImagingCodecStateInstance state;
|
struct ImagingCodecStateInstance state;
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
@ -58,8 +56,7 @@ typedef struct {
|
||||||
static PyTypeObject ImagingDecoderType;
|
static PyTypeObject ImagingDecoderType;
|
||||||
|
|
||||||
static ImagingDecoderObject *
|
static ImagingDecoderObject *
|
||||||
PyImaging_DecoderNew(int contextsize)
|
PyImaging_DecoderNew(int contextsize) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
void *context;
|
void *context;
|
||||||
|
|
||||||
|
@ -105,8 +102,7 @@ PyImaging_DecoderNew(int contextsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_dealloc(ImagingDecoderObject* decoder)
|
_dealloc(ImagingDecoderObject *decoder) {
|
||||||
{
|
|
||||||
if (decoder->cleanup) {
|
if (decoder->cleanup) {
|
||||||
decoder->cleanup(&decoder->state);
|
decoder->cleanup(&decoder->state);
|
||||||
}
|
}
|
||||||
|
@ -118,8 +114,7 @@ _dealloc(ImagingDecoderObject* decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_decode(ImagingDecoderObject* decoder, PyObject* args)
|
_decode(ImagingDecoderObject *decoder, PyObject *args) {
|
||||||
{
|
|
||||||
UINT8 *buffer;
|
UINT8 *buffer;
|
||||||
Py_ssize_t bufsize;
|
Py_ssize_t bufsize;
|
||||||
int status;
|
int status;
|
||||||
|
@ -143,8 +138,7 @@ _decode(ImagingDecoderObject* decoder, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_decode_cleanup(ImagingDecoderObject* decoder, PyObject* args)
|
_decode_cleanup(ImagingDecoderObject *decoder, PyObject *args) {
|
||||||
{
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
if (decoder->cleanup) {
|
if (decoder->cleanup) {
|
||||||
|
@ -154,13 +148,11 @@ _decode_cleanup(ImagingDecoderObject* decoder, PyObject* args)
|
||||||
return Py_BuildValue("i", status);
|
return Py_BuildValue("i", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern Imaging
|
||||||
|
PyImaging_AsImaging(PyObject *op);
|
||||||
extern Imaging PyImaging_AsImaging(PyObject *op);
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_setimage(ImagingDecoderObject* decoder, PyObject* args)
|
_setimage(ImagingDecoderObject *decoder, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *op;
|
PyObject *op;
|
||||||
Imaging im;
|
Imaging im;
|
||||||
ImagingCodecState state;
|
ImagingCodecState state;
|
||||||
|
@ -192,10 +184,8 @@ _setimage(ImagingDecoderObject* decoder, PyObject* args)
|
||||||
state->ysize = y1 - y0;
|
state->ysize = y1 - y0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->xsize <= 0 ||
|
if (state->xsize <= 0 || state->xsize + state->xoff > (int)im->xsize ||
|
||||||
state->xsize + state->xoff > (int) im->xsize ||
|
state->ysize <= 0 || state->ysize + state->yoff > (int)im->ysize) {
|
||||||
state->ysize <= 0 ||
|
|
||||||
state->ysize + state->yoff > (int) im->ysize) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "tile cannot extend outside image");
|
PyErr_SetString(PyExc_ValueError, "tile cannot extend outside image");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -226,8 +216,7 @@ _setimage(ImagingDecoderObject* decoder, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_setfd(ImagingDecoderObject* decoder, PyObject* args)
|
_setfd(ImagingDecoderObject *decoder, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *fd;
|
PyObject *fd;
|
||||||
ImagingCodecState state;
|
ImagingCodecState state;
|
||||||
|
|
||||||
|
@ -244,10 +233,8 @@ _setfd(ImagingDecoderObject* decoder, PyObject* args)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_get_pulls_fd(ImagingDecoderObject *decoder)
|
_get_pulls_fd(ImagingDecoderObject *decoder) {
|
||||||
{
|
|
||||||
return PyBool_FromLong(decoder->pulls_fd);
|
return PyBool_FromLong(decoder->pulls_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,15 +247,16 @@ static struct PyMethodDef methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct PyGetSetDef getseters[] = {
|
static struct PyGetSetDef getseters[] = {
|
||||||
{"pulls_fd", (getter)_get_pulls_fd, NULL,
|
{"pulls_fd",
|
||||||
|
(getter)_get_pulls_fd,
|
||||||
|
NULL,
|
||||||
"True if this decoder expects to pull from self.fd itself.",
|
"True if this decoder expects to pull from self.fd itself.",
|
||||||
NULL},
|
NULL},
|
||||||
{NULL, NULL, NULL, NULL, NULL} /* sentinel */
|
{NULL, NULL, NULL, NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyTypeObject ImagingDecoderType = {
|
static PyTypeObject ImagingDecoderType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "ImagingDecoder", /*tp_name*/
|
||||||
"ImagingDecoder", /*tp_name*/
|
|
||||||
sizeof(ImagingDecoderObject), /*tp_size*/
|
sizeof(ImagingDecoderObject), /*tp_size*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
/* methods */
|
/* methods */
|
||||||
|
@ -303,9 +291,7 @@ static PyTypeObject ImagingDecoderType = {
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
get_unpacker(ImagingDecoderObject* decoder, const char* mode,
|
get_unpacker(ImagingDecoderObject *decoder, const char *mode, const char *rawmode) {
|
||||||
const char* rawmode)
|
|
||||||
{
|
|
||||||
int bits;
|
int bits;
|
||||||
ImagingShuffler unpack;
|
ImagingShuffler unpack;
|
||||||
|
|
||||||
|
@ -322,14 +308,12 @@ get_unpacker(ImagingDecoderObject* decoder, const char* mode,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* BIT (packed fields) */
|
/* BIT (packed fields) */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_BitDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_BitDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -338,8 +322,7 @@ PyImaging_BitDecoderNew(PyObject* self, PyObject* args)
|
||||||
int fill = 0;
|
int fill = 0;
|
||||||
int sign = 0;
|
int sign = 0;
|
||||||
int ystep = 1;
|
int ystep = 1;
|
||||||
if (!PyArg_ParseTuple(args, "s|iiiii", &mode, &bits, &pad, &fill,
|
if (!PyArg_ParseTuple(args, "s|iiiii", &mode, &bits, &pad, &fill, &sign, &ystep)) {
|
||||||
&sign, &ystep)) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,14 +348,12 @@ PyImaging_BitDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* BCn: GPU block-compressed texture formats */
|
/* BCn: GPU block-compressed texture formats */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_BcnDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_BcnDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -389,12 +370,15 @@ PyImaging_BcnDecoderNew(PyObject* self, PyObject* args)
|
||||||
case 3: /* BC3: 565 color, 2-endpoint 8-bit interpolated alpha */
|
case 3: /* BC3: 565 color, 2-endpoint 8-bit interpolated alpha */
|
||||||
case 5: /* BC5: 2-channel 8-bit via 2 BC3 alpha blocks */
|
case 5: /* BC5: 2-channel 8-bit via 2 BC3 alpha blocks */
|
||||||
case 7: /* BC7: 4-channel 8-bit via everything */
|
case 7: /* BC7: 4-channel 8-bit via everything */
|
||||||
actual = "RGBA"; break;
|
actual = "RGBA";
|
||||||
|
break;
|
||||||
case 4: /* BC4: 1-channel 8-bit via 1 BC3 alpha block */
|
case 4: /* BC4: 1-channel 8-bit via 1 BC3 alpha block */
|
||||||
actual = "L"; break;
|
actual = "L";
|
||||||
|
break;
|
||||||
case 6: /* BC6: 3-channel 16-bit float */
|
case 6: /* BC6: 3-channel 16-bit float */
|
||||||
/* TODO: support 4-channel floating point images */
|
/* TODO: support 4-channel floating point images */
|
||||||
actual = "RGBAF"; break;
|
actual = "RGBAF";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_SetString(PyExc_ValueError, "block compression type unknown");
|
PyErr_SetString(PyExc_ValueError, "block compression type unknown");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -417,14 +401,12 @@ PyImaging_BcnDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* FLI */
|
/* FLI */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_FliDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_FliDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
decoder = PyImaging_DecoderNew(0);
|
decoder = PyImaging_DecoderNew(0);
|
||||||
|
@ -437,14 +419,12 @@ PyImaging_FliDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* GIF */
|
/* GIF */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_GifDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_GifDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -472,14 +452,12 @@ PyImaging_GifDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* HEX */
|
/* HEX */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_HexDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_HexDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -502,7 +480,6 @@ PyImaging_HexDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* LibTiff */
|
/* LibTiff */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -514,8 +491,7 @@ PyImaging_HexDecoderNew(PyObject* self, PyObject* args)
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_LibTiffDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
char *mode;
|
char *mode;
|
||||||
char *rawmode;
|
char *rawmode;
|
||||||
|
@ -551,14 +527,12 @@ PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* PackBits */
|
/* PackBits */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_PackbitsDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -581,14 +555,12 @@ PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* PCD */
|
/* PCD */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_PcdDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_PcdDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
decoder = PyImaging_DecoderNew(0);
|
decoder = PyImaging_DecoderNew(0);
|
||||||
|
@ -606,14 +578,12 @@ PyImaging_PcdDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* PCX */
|
/* PCX */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_PcxDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_PcxDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -639,14 +609,12 @@ PyImaging_PcxDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* RAW */
|
/* RAW */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_RawDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_RawDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -675,14 +643,12 @@ PyImaging_RawDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* SGI RLE */
|
/* SGI RLE */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_SgiRleDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_SgiRleDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -711,14 +677,12 @@ PyImaging_SgiRleDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* SUN RLE */
|
/* SUN RLE */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_SunRleDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_SunRleDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -741,14 +705,12 @@ PyImaging_SunRleDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* TGA RLE */
|
/* TGA RLE */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_TgaRleDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_TgaRleDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -776,14 +738,12 @@ PyImaging_TgaRleDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* XBM */
|
/* XBM */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_XbmDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_XbmDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
decoder = PyImaging_DecoderNew(0);
|
decoder = PyImaging_DecoderNew(0);
|
||||||
|
@ -800,7 +760,6 @@ PyImaging_XbmDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* ZIP */
|
/* ZIP */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -810,8 +769,7 @@ PyImaging_XbmDecoderNew(PyObject* self, PyObject* args)
|
||||||
#include "libImaging/ZipCodecs.h"
|
#include "libImaging/ZipCodecs.h"
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_ZipDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_ZipDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -839,7 +797,6 @@ PyImaging_ZipDecoderNew(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* JPEG */
|
/* JPEG */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -862,8 +819,7 @@ PyImaging_ZipDecoderNew(PyObject* self, PyObject* args)
|
||||||
#include "libImaging/Jpeg.h"
|
#include "libImaging/Jpeg.h"
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_JpegDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_JpegDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -872,8 +828,7 @@ PyImaging_JpegDecoderNew(PyObject* self, PyObject* args)
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
int draft = 0;
|
int draft = 0;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode,
|
if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode, &scale, &draft)) {
|
||||||
&scale, &draft)) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,8 +874,7 @@ PyImaging_JpegDecoderNew(PyObject* self, PyObject* args)
|
||||||
#include "libImaging/Jpeg2K.h"
|
#include "libImaging/Jpeg2K.h"
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_Jpeg2KDecoderNew(PyObject* self, PyObject* args)
|
PyImaging_Jpeg2KDecoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDecoderObject *decoder;
|
ImagingDecoderObject *decoder;
|
||||||
JPEG2KDECODESTATE *context;
|
JPEG2KDECODESTATE *context;
|
||||||
|
|
||||||
|
@ -932,8 +886,8 @@ PyImaging_Jpeg2KDecoderNew(PyObject* self, PyObject* args)
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
PY_LONG_LONG length = -1;
|
PY_LONG_LONG length = -1;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ss|iiiL", &mode, &format,
|
if (!PyArg_ParseTuple(
|
||||||
&reduce, &layers, &fd, &length)) {
|
args, "ss|iiiL", &mode, &format, &reduce, &layers, &fd, &length)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,4 +921,3 @@ PyImaging_Jpeg2KDecoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)decoder;
|
return (PyObject *)decoder;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENJPEG */
|
#endif /* HAVE_OPENJPEG */
|
||||||
|
|
||||||
|
|
252
src/display.c
252
src/display.c
|
@ -41,15 +41,13 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD ImagingDIB dib;
|
||||||
ImagingDIB dib;
|
|
||||||
} ImagingDisplayObject;
|
} ImagingDisplayObject;
|
||||||
|
|
||||||
static PyTypeObject ImagingDisplayType;
|
static PyTypeObject ImagingDisplayType;
|
||||||
|
|
||||||
static ImagingDisplayObject *
|
static ImagingDisplayObject *
|
||||||
_new(const char* mode, int xsize, int ysize)
|
_new(const char *mode, int xsize, int ysize) {
|
||||||
{
|
|
||||||
ImagingDisplayObject *display;
|
ImagingDisplayObject *display;
|
||||||
|
|
||||||
if (PyType_Ready(&ImagingDisplayType) < 0) {
|
if (PyType_Ready(&ImagingDisplayType) < 0) {
|
||||||
|
@ -71,8 +69,7 @@ _new(const char* mode, int xsize, int ysize)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_delete(ImagingDisplayObject* display)
|
_delete(ImagingDisplayObject *display) {
|
||||||
{
|
|
||||||
if (display->dib) {
|
if (display->dib) {
|
||||||
ImagingDeleteDIB(display->dib);
|
ImagingDeleteDIB(display->dib);
|
||||||
}
|
}
|
||||||
|
@ -80,8 +77,7 @@ _delete(ImagingDisplayObject* display)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_expose(ImagingDisplayObject* display, PyObject* args)
|
_expose(ImagingDisplayObject *display, PyObject *args) {
|
||||||
{
|
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
if (!PyArg_ParseTuple(args, F_HANDLE, &hdc)) {
|
if (!PyArg_ParseTuple(args, F_HANDLE, &hdc)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -94,14 +90,22 @@ _expose(ImagingDisplayObject* display, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_draw(ImagingDisplayObject* display, PyObject* args)
|
_draw(ImagingDisplayObject *display, PyObject *args) {
|
||||||
{
|
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
int dst[4];
|
int dst[4];
|
||||||
int src[4];
|
int src[4];
|
||||||
if (!PyArg_ParseTuple(args, F_HANDLE "(iiii)(iiii)", &hdc,
|
if (!PyArg_ParseTuple(
|
||||||
dst+0, dst+1, dst+2, dst+3,
|
args,
|
||||||
src+0, src+1, src+2, src+3)) {
|
F_HANDLE "(iiii)(iiii)",
|
||||||
|
&hdc,
|
||||||
|
dst + 0,
|
||||||
|
dst + 1,
|
||||||
|
dst + 2,
|
||||||
|
dst + 3,
|
||||||
|
src + 0,
|
||||||
|
src + 1,
|
||||||
|
src + 2,
|
||||||
|
src + 3)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,11 +115,11 @@ _draw(ImagingDisplayObject* display, PyObject* args)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern Imaging PyImaging_AsImaging(PyObject *op);
|
extern Imaging
|
||||||
|
PyImaging_AsImaging(PyObject *op);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_paste(ImagingDisplayObject* display, PyObject* args)
|
_paste(ImagingDisplayObject *display, PyObject *args) {
|
||||||
{
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
|
||||||
PyObject *op;
|
PyObject *op;
|
||||||
|
@ -143,8 +147,7 @@ _paste(ImagingDisplayObject* display, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_query_palette(ImagingDisplayObject* display, PyObject* args)
|
_query_palette(ImagingDisplayObject *display, PyObject *args) {
|
||||||
{
|
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
@ -158,8 +161,7 @@ _query_palette(ImagingDisplayObject* display, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_getdc(ImagingDisplayObject* display, PyObject* args)
|
_getdc(ImagingDisplayObject *display, PyObject *args) {
|
||||||
{
|
|
||||||
HWND window;
|
HWND window;
|
||||||
HDC dc;
|
HDC dc;
|
||||||
|
|
||||||
|
@ -177,8 +179,7 @@ _getdc(ImagingDisplayObject* display, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_releasedc(ImagingDisplayObject* display, PyObject* args)
|
_releasedc(ImagingDisplayObject *display, PyObject *args) {
|
||||||
{
|
|
||||||
HWND window;
|
HWND window;
|
||||||
HDC dc;
|
HDC dc;
|
||||||
|
|
||||||
|
@ -193,8 +194,7 @@ _releasedc(ImagingDisplayObject* display, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_frombytes(ImagingDisplayObject* display, PyObject* args)
|
_frombytes(ImagingDisplayObject *display, PyObject *args) {
|
||||||
{
|
|
||||||
char *ptr;
|
char *ptr;
|
||||||
Py_ssize_t bytes;
|
Py_ssize_t bytes;
|
||||||
|
|
||||||
|
@ -214,15 +214,13 @@ _frombytes(ImagingDisplayObject* display, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_tobytes(ImagingDisplayObject* display, PyObject* args)
|
_tobytes(ImagingDisplayObject *display, PyObject *args) {
|
||||||
{
|
|
||||||
if (!PyArg_ParseTuple(args, ":tobytes")) {
|
if (!PyArg_ParseTuple(args, ":tobytes")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PyBytes_FromStringAndSize(
|
return PyBytes_FromStringAndSize(
|
||||||
display->dib->bits, display->dib->ysize * display->dib->linesize
|
display->dib->bits, display->dib->ysize * display->dib->linesize);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct PyMethodDef methods[] = {
|
static struct PyMethodDef methods[] = {
|
||||||
|
@ -238,26 +236,20 @@ static struct PyMethodDef methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_getattr_mode(ImagingDisplayObject* self, void* closure)
|
_getattr_mode(ImagingDisplayObject *self, void *closure) {
|
||||||
{
|
|
||||||
return Py_BuildValue("s", self->dib->mode);
|
return Py_BuildValue("s", self->dib->mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_getattr_size(ImagingDisplayObject* self, void* closure)
|
_getattr_size(ImagingDisplayObject *self, void *closure) {
|
||||||
{
|
|
||||||
return Py_BuildValue("ii", self->dib->xsize, self->dib->ysize);
|
return Py_BuildValue("ii", self->dib->xsize, self->dib->ysize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct PyGetSetDef getsetters[] = {
|
static struct PyGetSetDef getsetters[] = {
|
||||||
{ "mode", (getter) _getattr_mode },
|
{"mode", (getter)_getattr_mode}, {"size", (getter)_getattr_size}, {NULL}};
|
||||||
{ "size", (getter) _getattr_size },
|
|
||||||
{ NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject ImagingDisplayType = {
|
static PyTypeObject ImagingDisplayType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "ImagingDisplay", /*tp_name*/
|
||||||
"ImagingDisplay", /*tp_name*/
|
|
||||||
sizeof(ImagingDisplayObject), /*tp_size*/
|
sizeof(ImagingDisplayObject), /*tp_size*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
/* methods */
|
/* methods */
|
||||||
|
@ -290,8 +282,7 @@ static PyTypeObject ImagingDisplayType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_DisplayWin32(PyObject* self, PyObject* args)
|
PyImaging_DisplayWin32(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingDisplayObject *display;
|
ImagingDisplayObject *display;
|
||||||
char *mode;
|
char *mode;
|
||||||
int xsize, ysize;
|
int xsize, ysize;
|
||||||
|
@ -309,8 +300,7 @@ PyImaging_DisplayWin32(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_DisplayModeWin32(PyObject* self, PyObject* args)
|
PyImaging_DisplayModeWin32(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
char *mode;
|
char *mode;
|
||||||
int size[2];
|
int size[2];
|
||||||
|
|
||||||
|
@ -325,8 +315,7 @@ PyImaging_DisplayModeWin32(PyObject* self, PyObject* args)
|
||||||
typedef HANDLE(__stdcall *Func_SetThreadDpiAwarenessContext)(HANDLE);
|
typedef HANDLE(__stdcall *Func_SetThreadDpiAwarenessContext)(HANDLE);
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
|
PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
int x = 0, y = 0, width, height;
|
int x = 0, y = 0, width, height;
|
||||||
int includeLayeredWindows = 0, all_screens = 0;
|
int includeLayeredWindows = 0, all_screens = 0;
|
||||||
HBITMAP bitmap;
|
HBITMAP bitmap;
|
||||||
|
@ -352,8 +341,8 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
|
||||||
// loaded dynamically to avoid link errors
|
// loaded dynamically to avoid link errors
|
||||||
user32 = LoadLibraryA("User32.dll");
|
user32 = LoadLibraryA("User32.dll");
|
||||||
SetThreadDpiAwarenessContext_function =
|
SetThreadDpiAwarenessContext_function =
|
||||||
(Func_SetThreadDpiAwarenessContext)
|
(Func_SetThreadDpiAwarenessContext)GetProcAddress(
|
||||||
GetProcAddress(user32, "SetThreadDpiAwarenessContext");
|
user32, "SetThreadDpiAwarenessContext");
|
||||||
if (SetThreadDpiAwarenessContext_function != NULL) {
|
if (SetThreadDpiAwarenessContext_function != NULL) {
|
||||||
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = ((DPI_CONTEXT_HANDLE)-3)
|
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = ((DPI_CONTEXT_HANDLE)-3)
|
||||||
dpiAwareness = SetThreadDpiAwarenessContext_function((HANDLE)-3);
|
dpiAwareness = SetThreadDpiAwarenessContext_function((HANDLE)-3);
|
||||||
|
@ -406,8 +395,14 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
|
||||||
core.bcHeight = height;
|
core.bcHeight = height;
|
||||||
core.bcPlanes = 1;
|
core.bcPlanes = 1;
|
||||||
core.bcBitCount = 24;
|
core.bcBitCount = 24;
|
||||||
if (!GetDIBits(screen_copy, bitmap, 0, height, PyBytes_AS_STRING(buffer),
|
if (!GetDIBits(
|
||||||
(BITMAPINFO*) &core, DIB_RGB_COLORS)) {
|
screen_copy,
|
||||||
|
bitmap,
|
||||||
|
0,
|
||||||
|
height,
|
||||||
|
PyBytes_AS_STRING(buffer),
|
||||||
|
(BITMAPINFO *)&core,
|
||||||
|
DIB_RGB_COLORS)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,8 +421,8 @@ error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CALLBACK list_windows_callback(HWND hwnd, LPARAM lParam)
|
static BOOL CALLBACK
|
||||||
{
|
list_windows_callback(HWND hwnd, LPARAM lParam) {
|
||||||
PyObject *window_list = (PyObject *)lParam;
|
PyObject *window_list = (PyObject *)lParam;
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
PyObject *title;
|
PyObject *title;
|
||||||
|
@ -454,10 +449,17 @@ static BOOL CALLBACK list_windows_callback(HWND hwnd, LPARAM lParam)
|
||||||
GetWindowRect(hwnd, &outer);
|
GetWindowRect(hwnd, &outer);
|
||||||
|
|
||||||
item = Py_BuildValue(
|
item = Py_BuildValue(
|
||||||
F_HANDLE "N(iiii)(iiii)", hwnd, title,
|
F_HANDLE "N(iiii)(iiii)",
|
||||||
inner.left, inner.top, inner.right, inner.bottom,
|
hwnd,
|
||||||
outer.left, outer.top, outer.right, outer.bottom
|
title,
|
||||||
);
|
inner.left,
|
||||||
|
inner.top,
|
||||||
|
inner.right,
|
||||||
|
inner.bottom,
|
||||||
|
outer.left,
|
||||||
|
outer.top,
|
||||||
|
outer.right,
|
||||||
|
outer.bottom);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -474,8 +476,7 @@ static BOOL CALLBACK list_windows_callback(HWND hwnd, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_ListWindowsWin32(PyObject* self, PyObject* args)
|
PyImaging_ListWindowsWin32(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *window_list;
|
PyObject *window_list;
|
||||||
|
|
||||||
window_list = PyList_New(0);
|
window_list = PyList_New(0);
|
||||||
|
@ -497,8 +498,7 @@ PyImaging_ListWindowsWin32(PyObject* self, PyObject* args)
|
||||||
/* Windows clipboard grabber */
|
/* Windows clipboard grabber */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_GrabClipboardWin32(PyObject* self, PyObject* args)
|
PyImaging_GrabClipboardWin32(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
int clip;
|
int clip;
|
||||||
HANDLE handle = NULL;
|
HANDLE handle = NULL;
|
||||||
int size;
|
int size;
|
||||||
|
@ -551,8 +551,7 @@ PyImaging_GrabClipboardWin32(PyObject* self, PyObject* args)
|
||||||
static int mainloop = 0;
|
static int mainloop = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
callback_error(const char* handler)
|
callback_error(const char *handler) {
|
||||||
{
|
|
||||||
PyObject *sys_stderr;
|
PyObject *sys_stderr;
|
||||||
|
|
||||||
sys_stderr = PySys_GetObject("stderr");
|
sys_stderr = PySys_GetObject("stderr");
|
||||||
|
@ -568,8 +567,7 @@ callback_error(const char* handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
static LRESULT CALLBACK
|
static LRESULT CALLBACK
|
||||||
windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
|
windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||||
{
|
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
PyObject *callback = NULL;
|
PyObject *callback = NULL;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
@ -591,8 +589,8 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
callback = (PyObject *)GetWindowLongPtr(wnd, 0);
|
callback = (PyObject *)GetWindowLongPtr(wnd, 0);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
threadstate = (PyThreadState*)
|
threadstate =
|
||||||
GetWindowLongPtr(wnd, sizeof(PyObject*));
|
(PyThreadState *)GetWindowLongPtr(wnd, sizeof(PyObject *));
|
||||||
current_threadstate = PyThreadState_Swap(NULL);
|
current_threadstate = PyThreadState_Swap(NULL);
|
||||||
PyEval_RestoreThread(threadstate);
|
PyEval_RestoreThread(threadstate);
|
||||||
} else {
|
} else {
|
||||||
|
@ -602,7 +600,6 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
/* process message */
|
/* process message */
|
||||||
switch (message) {
|
switch (message) {
|
||||||
|
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
/* redraw (part of) window. this generates a WCK-style
|
/* redraw (part of) window. this generates a WCK-style
|
||||||
damage/clear/repair cascade */
|
damage/clear/repair cascade */
|
||||||
|
@ -611,10 +608,13 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
GetWindowRect(wnd, &rect); /* in screen coordinates */
|
GetWindowRect(wnd, &rect); /* in screen coordinates */
|
||||||
|
|
||||||
result = PyObject_CallFunction(
|
result = PyObject_CallFunction(
|
||||||
callback, "siiii", "damage",
|
callback,
|
||||||
ps.rcPaint.left, ps.rcPaint.top,
|
"siiii",
|
||||||
ps.rcPaint.right, ps.rcPaint.bottom
|
"damage",
|
||||||
);
|
ps.rcPaint.left,
|
||||||
|
ps.rcPaint.top,
|
||||||
|
ps.rcPaint.right,
|
||||||
|
ps.rcPaint.bottom);
|
||||||
if (result) {
|
if (result) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -622,9 +622,14 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
result = PyObject_CallFunction(
|
result = PyObject_CallFunction(
|
||||||
callback, "s" F_HANDLE "iiii", "clear", dc,
|
callback,
|
||||||
0, 0, rect.right-rect.left, rect.bottom-rect.top
|
"s" F_HANDLE "iiii",
|
||||||
);
|
"clear",
|
||||||
|
dc,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
rect.right - rect.left,
|
||||||
|
rect.bottom - rect.top);
|
||||||
if (result) {
|
if (result) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -632,9 +637,14 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
result = PyObject_CallFunction(
|
result = PyObject_CallFunction(
|
||||||
callback, "s" F_HANDLE "iiii", "repair", dc,
|
callback,
|
||||||
0, 0, rect.right-rect.left, rect.bottom-rect.top
|
"s" F_HANDLE "iiii",
|
||||||
);
|
"repair",
|
||||||
|
dc,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
rect.right - rect.left,
|
||||||
|
rect.bottom - rect.top);
|
||||||
if (result) {
|
if (result) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -648,8 +658,7 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
/* resize window */
|
/* resize window */
|
||||||
result = PyObject_CallFunction(
|
result = PyObject_CallFunction(
|
||||||
callback, "sii", "resize", LOWORD(lParam), HIWORD(lParam)
|
callback, "sii", "resize", LOWORD(lParam), HIWORD(lParam));
|
||||||
);
|
|
||||||
if (result) {
|
if (result) {
|
||||||
InvalidateRect(wnd, NULL, 1);
|
InvalidateRect(wnd, NULL, 1);
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
@ -683,8 +692,7 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_CreateWindowWin32(PyObject* self, PyObject* args)
|
PyImaging_CreateWindowWin32(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
HWND wnd;
|
HWND wnd;
|
||||||
WNDCLASS windowClass;
|
WNDCLASS windowClass;
|
||||||
|
|
||||||
|
@ -718,11 +726,18 @@ PyImaging_CreateWindowWin32(PyObject* self, PyObject* args)
|
||||||
RegisterClass(&windowClass); /* FIXME: check return status */
|
RegisterClass(&windowClass); /* FIXME: check return status */
|
||||||
|
|
||||||
wnd = CreateWindowEx(
|
wnd = CreateWindowEx(
|
||||||
0, windowClass.lpszClassName, title,
|
0,
|
||||||
|
windowClass.lpszClassName,
|
||||||
|
title,
|
||||||
WS_OVERLAPPEDWINDOW,
|
WS_OVERLAPPEDWINDOW,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
|
CW_USEDEFAULT,
|
||||||
HWND_DESKTOP, NULL, NULL, NULL
|
CW_USEDEFAULT,
|
||||||
);
|
width,
|
||||||
|
height,
|
||||||
|
HWND_DESKTOP,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!wnd) {
|
if (!wnd) {
|
||||||
PyErr_SetString(PyExc_OSError, "failed to create window");
|
PyErr_SetString(PyExc_OSError, "failed to create window");
|
||||||
|
@ -734,8 +749,7 @@ PyImaging_CreateWindowWin32(PyObject* self, PyObject* args)
|
||||||
SetWindowLongPtr(wnd, 0, (LONG_PTR)callback);
|
SetWindowLongPtr(wnd, 0, (LONG_PTR)callback);
|
||||||
SetWindowLongPtr(wnd, sizeof(callback), (LONG_PTR)PyThreadState_Get());
|
SetWindowLongPtr(wnd, sizeof(callback), (LONG_PTR)PyThreadState_Get());
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS ShowWindow(wnd, SW_SHOWNORMAL);
|
||||||
ShowWindow(wnd, SW_SHOWNORMAL);
|
|
||||||
SetForegroundWindow(wnd); /* to make sure it's visible */
|
SetForegroundWindow(wnd); /* to make sure it's visible */
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
|
@ -743,12 +757,10 @@ PyImaging_CreateWindowWin32(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_EventLoopWin32(PyObject* self, PyObject* args)
|
PyImaging_EventLoopWin32(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS while (mainloop && GetMessage(&msg, NULL, 0, 0)) {
|
||||||
while (mainloop && GetMessage(&msg, NULL, 0, 0)) {
|
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
@ -764,8 +776,7 @@ PyImaging_EventLoopWin32(PyObject* self, PyObject* args)
|
||||||
#define GET32(p, o) ((DWORD *)(p + o))[0]
|
#define GET32(p, o) ((DWORD *)(p + o))[0]
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_DrawWmf(PyObject* self, PyObject* args)
|
PyImaging_DrawWmf(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
HBITMAP bitmap;
|
HBITMAP bitmap;
|
||||||
HENHMETAFILE meta;
|
HENHMETAFILE meta;
|
||||||
BITMAPCOREHEADER core;
|
BITMAPCOREHEADER core;
|
||||||
|
@ -778,29 +789,33 @@ PyImaging_DrawWmf(PyObject* self, PyObject* args)
|
||||||
Py_ssize_t datasize;
|
Py_ssize_t datasize;
|
||||||
int width, height;
|
int width, height;
|
||||||
int x0, y0, x1, y1;
|
int x0, y0, x1, y1;
|
||||||
if (!PyArg_ParseTuple(args, "y#(ii)(iiii):_load", &data, &datasize,
|
if (!PyArg_ParseTuple(
|
||||||
&width, &height, &x0, &x1, &y0, &y1)) {
|
args,
|
||||||
|
"y#(ii)(iiii):_load",
|
||||||
|
&data,
|
||||||
|
&datasize,
|
||||||
|
&width,
|
||||||
|
&height,
|
||||||
|
&x0,
|
||||||
|
&x1,
|
||||||
|
&y0,
|
||||||
|
&y1)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* step 1: copy metafile contents into METAFILE object */
|
/* step 1: copy metafile contents into METAFILE object */
|
||||||
|
|
||||||
if (datasize > 22 && GET32(data, 0) == 0x9ac6cdd7) {
|
if (datasize > 22 && GET32(data, 0) == 0x9ac6cdd7) {
|
||||||
|
|
||||||
/* placeable windows metafile (22-byte aldus header) */
|
/* placeable windows metafile (22-byte aldus header) */
|
||||||
meta = SetWinMetaFileBits(datasize - 22, data + 22, NULL, NULL);
|
meta = SetWinMetaFileBits(datasize - 22, data + 22, NULL, NULL);
|
||||||
|
|
||||||
} else if (datasize > 80 && GET32(data, 0) == 1 &&
|
} else if (datasize > 80 && GET32(data, 0) == 1 && GET32(data, 40) == 0x464d4520) {
|
||||||
GET32(data, 40) == 0x464d4520) {
|
|
||||||
|
|
||||||
/* enhanced metafile */
|
/* enhanced metafile */
|
||||||
meta = SetEnhMetaFileBits(datasize, data);
|
meta = SetEnhMetaFileBits(datasize, data);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* unknown meta format */
|
/* unknown meta format */
|
||||||
meta = NULL;
|
meta = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
|
@ -818,9 +833,7 @@ PyImaging_DrawWmf(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
dc = CreateCompatibleDC(NULL);
|
dc = CreateCompatibleDC(NULL);
|
||||||
|
|
||||||
bitmap = CreateDIBSection(
|
bitmap = CreateDIBSection(dc, (BITMAPINFO *)&core, DIB_RGB_COLORS, &ptr, NULL, 0);
|
||||||
dc, (BITMAPINFO*) &core, DIB_RGB_COLORS, &ptr, NULL, 0
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!bitmap) {
|
if (!bitmap) {
|
||||||
PyErr_SetString(PyExc_OSError, "cannot create bitmap");
|
PyErr_SetString(PyExc_OSError, "cannot create bitmap");
|
||||||
|
@ -876,8 +889,7 @@ error:
|
||||||
/* X11 screen grabber */
|
/* X11 screen grabber */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_GrabScreenX11(PyObject* self, PyObject* args)
|
PyImaging_GrabScreenX11(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
int width, height;
|
int width, height;
|
||||||
char *display_name;
|
char *display_name;
|
||||||
xcb_connection_t *connection;
|
xcb_connection_t *connection;
|
||||||
|
@ -896,7 +908,10 @@ PyImaging_GrabScreenX11(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
connection = xcb_connect(display_name, &screen_number);
|
connection = xcb_connect(display_name, &screen_number);
|
||||||
if (xcb_connection_has_error(connection)) {
|
if (xcb_connection_has_error(connection)) {
|
||||||
PyErr_Format(PyExc_OSError, "X connection failed: error %i", xcb_connection_has_error(connection));
|
PyErr_Format(
|
||||||
|
PyExc_OSError,
|
||||||
|
"X connection failed: error %i",
|
||||||
|
xcb_connection_has_error(connection));
|
||||||
xcb_disconnect(connection);
|
xcb_disconnect(connection);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -920,13 +935,26 @@ PyImaging_GrabScreenX11(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
/* get image data */
|
/* get image data */
|
||||||
|
|
||||||
reply = xcb_get_image_reply(connection,
|
reply = xcb_get_image_reply(
|
||||||
xcb_get_image(connection, XCB_IMAGE_FORMAT_Z_PIXMAP, screen->root,
|
connection,
|
||||||
0, 0, width, height, 0x00ffffff),
|
xcb_get_image(
|
||||||
|
connection,
|
||||||
|
XCB_IMAGE_FORMAT_Z_PIXMAP,
|
||||||
|
screen->root,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
0x00ffffff),
|
||||||
&error);
|
&error);
|
||||||
if (reply == NULL) {
|
if (reply == NULL) {
|
||||||
PyErr_Format(PyExc_OSError, "X get_image failed: error %i (%i, %i, %i)",
|
PyErr_Format(
|
||||||
error->error_code, error->major_code, error->minor_code, error->resource_id);
|
PyExc_OSError,
|
||||||
|
"X get_image failed: error %i (%i, %i, %i)",
|
||||||
|
error->error_code,
|
||||||
|
error->major_code,
|
||||||
|
error->minor_code,
|
||||||
|
error->resource_id);
|
||||||
free(error);
|
free(error);
|
||||||
xcb_disconnect(connection);
|
xcb_disconnect(connection);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -935,8 +963,8 @@ PyImaging_GrabScreenX11(PyObject* self, PyObject* args)
|
||||||
/* store data in Python buffer */
|
/* store data in Python buffer */
|
||||||
|
|
||||||
if (reply->depth == 24) {
|
if (reply->depth == 24) {
|
||||||
buffer = PyBytes_FromStringAndSize((char*)xcb_get_image_data(reply),
|
buffer = PyBytes_FromStringAndSize(
|
||||||
xcb_get_image_data_length(reply));
|
(char *)xcb_get_image_data(reply), xcb_get_image_data_length(reply));
|
||||||
} else {
|
} else {
|
||||||
PyErr_Format(PyExc_OSError, "unsupported bit depth: %i", reply->depth);
|
PyErr_Format(PyExc_OSError, "unsupported bit depth: %i", reply->depth);
|
||||||
}
|
}
|
||||||
|
|
311
src/encode.c
311
src/encode.c
|
@ -37,9 +37,8 @@
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD int (*encode)(
|
||||||
int (*encode)(Imaging im, ImagingCodecState state,
|
Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
UINT8* buffer, int bytes);
|
|
||||||
int (*cleanup)(ImagingCodecState state);
|
int (*cleanup)(ImagingCodecState state);
|
||||||
struct ImagingCodecStateInstance state;
|
struct ImagingCodecStateInstance state;
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
@ -50,8 +49,7 @@ typedef struct {
|
||||||
static PyTypeObject ImagingEncoderType;
|
static PyTypeObject ImagingEncoderType;
|
||||||
|
|
||||||
static ImagingEncoderObject *
|
static ImagingEncoderObject *
|
||||||
PyImaging_EncoderNew(int contextsize)
|
PyImaging_EncoderNew(int contextsize) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
void *context;
|
void *context;
|
||||||
|
|
||||||
|
@ -94,8 +92,7 @@ PyImaging_EncoderNew(int contextsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_dealloc(ImagingEncoderObject* encoder)
|
_dealloc(ImagingEncoderObject *encoder) {
|
||||||
{
|
|
||||||
if (encoder->cleanup) {
|
if (encoder->cleanup) {
|
||||||
encoder->cleanup(&encoder->state);
|
encoder->cleanup(&encoder->state);
|
||||||
}
|
}
|
||||||
|
@ -107,8 +104,7 @@ _dealloc(ImagingEncoderObject* encoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_encode_cleanup(ImagingEncoderObject* encoder, PyObject* args)
|
_encode_cleanup(ImagingEncoderObject *encoder, PyObject *args) {
|
||||||
{
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
if (encoder->cleanup) {
|
if (encoder->cleanup) {
|
||||||
|
@ -119,8 +115,7 @@ _encode_cleanup(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_encode(ImagingEncoderObject* encoder, PyObject* args)
|
_encode(ImagingEncoderObject *encoder, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *buf;
|
PyObject *buf;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
int status;
|
int status;
|
||||||
|
@ -138,8 +133,8 @@ _encode(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = encoder->encode(encoder->im, &encoder->state,
|
status = encoder->encode(
|
||||||
(UINT8*) PyBytes_AsString(buf), bufsize);
|
encoder->im, &encoder->state, (UINT8 *)PyBytes_AsString(buf), bufsize);
|
||||||
|
|
||||||
/* adjust string length to avoid slicing in encoder */
|
/* adjust string length to avoid slicing in encoder */
|
||||||
if (_PyBytes_Resize(&buf, (status > 0) ? status : 0) < 0) {
|
if (_PyBytes_Resize(&buf, (status > 0) ? status : 0) < 0) {
|
||||||
|
@ -154,20 +149,18 @@ _encode(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_encode_to_pyfd(ImagingEncoderObject* encoder, PyObject* args)
|
_encode_to_pyfd(ImagingEncoderObject *encoder, PyObject *args) {
|
||||||
{
|
|
||||||
|
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!encoder->pushes_fd) {
|
if (!encoder->pushes_fd) {
|
||||||
// UNDONE, appropriate errcode???
|
// UNDONE, appropriate errcode???
|
||||||
result = Py_BuildValue("ii", 0, IMAGING_CODEC_CONFIG);;
|
result = Py_BuildValue("ii", 0, IMAGING_CODEC_CONFIG);
|
||||||
|
;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = encoder->encode(encoder->im, &encoder->state,
|
status = encoder->encode(encoder->im, &encoder->state, (UINT8 *)NULL, 0);
|
||||||
(UINT8*) NULL, 0);
|
|
||||||
|
|
||||||
result = Py_BuildValue("ii", status, encoder->state.errcode);
|
result = Py_BuildValue("ii", status, encoder->state.errcode);
|
||||||
|
|
||||||
|
@ -175,8 +168,7 @@ _encode_to_pyfd(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_encode_to_file(ImagingEncoderObject* encoder, PyObject* args)
|
_encode_to_file(ImagingEncoderObject *encoder, PyObject *args) {
|
||||||
{
|
|
||||||
UINT8 *buf;
|
UINT8 *buf;
|
||||||
int status;
|
int status;
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
|
@ -200,7 +192,6 @@ _encode_to_file(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
/* This replaces the inner loop in the ImageFile _save
|
/* This replaces the inner loop in the ImageFile _save
|
||||||
function. */
|
function. */
|
||||||
|
|
||||||
|
@ -223,11 +214,11 @@ _encode_to_file(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
return Py_BuildValue("i", encoder->state.errcode);
|
return Py_BuildValue("i", encoder->state.errcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern Imaging PyImaging_AsImaging(PyObject *op);
|
extern Imaging
|
||||||
|
PyImaging_AsImaging(PyObject *op);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_setimage(ImagingEncoderObject* encoder, PyObject* args)
|
_setimage(ImagingEncoderObject *encoder, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *op;
|
PyObject *op;
|
||||||
Imaging im;
|
Imaging im;
|
||||||
ImagingCodecState state;
|
ImagingCodecState state;
|
||||||
|
@ -260,10 +251,8 @@ _setimage(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
state->ysize = y1 - y0;
|
state->ysize = y1 - y0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->xsize <= 0 ||
|
if (state->xsize <= 0 || state->xsize + state->xoff > im->xsize ||
|
||||||
state->xsize + state->xoff > im->xsize ||
|
state->ysize <= 0 || state->ysize + state->yoff > im->ysize) {
|
||||||
state->ysize <= 0 ||
|
|
||||||
state->ysize + state->yoff > im->ysize) {
|
|
||||||
PyErr_SetString(PyExc_SystemError, "tile cannot extend outside image");
|
PyErr_SetString(PyExc_SystemError, "tile cannot extend outside image");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -292,8 +281,7 @@ _setimage(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_setfd(ImagingEncoderObject* encoder, PyObject* args)
|
_setfd(ImagingEncoderObject *encoder, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *fd;
|
PyObject *fd;
|
||||||
ImagingCodecState state;
|
ImagingCodecState state;
|
||||||
|
|
||||||
|
@ -311,8 +299,7 @@ _setfd(ImagingEncoderObject* encoder, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_get_pushes_fd(ImagingEncoderObject *encoder)
|
_get_pushes_fd(ImagingEncoderObject *encoder) {
|
||||||
{
|
|
||||||
return PyBool_FromLong(encoder->pushes_fd);
|
return PyBool_FromLong(encoder->pushes_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,15 +314,16 @@ static struct PyMethodDef methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct PyGetSetDef getseters[] = {
|
static struct PyGetSetDef getseters[] = {
|
||||||
{"pushes_fd", (getter)_get_pushes_fd, NULL,
|
{"pushes_fd",
|
||||||
|
(getter)_get_pushes_fd,
|
||||||
|
NULL,
|
||||||
"True if this decoder expects to push directly to self.fd",
|
"True if this decoder expects to push directly to self.fd",
|
||||||
NULL},
|
NULL},
|
||||||
{NULL, NULL, NULL, NULL, NULL} /* sentinel */
|
{NULL, NULL, NULL, NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyTypeObject ImagingEncoderType = {
|
static PyTypeObject ImagingEncoderType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "ImagingEncoder", /*tp_name*/
|
||||||
"ImagingEncoder", /*tp_name*/
|
|
||||||
sizeof(ImagingEncoderObject), /*tp_size*/
|
sizeof(ImagingEncoderObject), /*tp_size*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
/* methods */
|
/* methods */
|
||||||
|
@ -370,9 +358,7 @@ static PyTypeObject ImagingEncoderType = {
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
get_packer(ImagingEncoderObject* encoder, const char* mode,
|
get_packer(ImagingEncoderObject *encoder, const char *mode, const char *rawmode) {
|
||||||
const char* rawmode)
|
|
||||||
{
|
|
||||||
int bits;
|
int bits;
|
||||||
ImagingShuffler pack;
|
ImagingShuffler pack;
|
||||||
|
|
||||||
|
@ -389,14 +375,12 @@ get_packer(ImagingEncoderObject* encoder, const char* mode,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* EPS */
|
/* EPS */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_EpsEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_EpsEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
encoder = PyImaging_EncoderNew(0);
|
encoder = PyImaging_EncoderNew(0);
|
||||||
|
@ -409,14 +393,12 @@ PyImaging_EpsEncoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)encoder;
|
return (PyObject *)encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* GIF */
|
/* GIF */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_GifEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_GifEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -444,14 +426,12 @@ PyImaging_GifEncoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)encoder;
|
return (PyObject *)encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* PCX */
|
/* PCX */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_PcxEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_PcxEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -476,14 +456,12 @@ PyImaging_PcxEncoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)encoder;
|
return (PyObject *)encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* RAW */
|
/* RAW */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_RawEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_RawEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -512,14 +490,12 @@ PyImaging_RawEncoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)encoder;
|
return (PyObject *)encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* TGA */
|
/* TGA */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_TgaRleEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_TgaRleEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -546,15 +522,12 @@ PyImaging_TgaRleEncoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)encoder;
|
return (PyObject *)encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* XBM */
|
/* XBM */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_XbmEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_XbmEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
encoder = PyImaging_EncoderNew(0);
|
encoder = PyImaging_EncoderNew(0);
|
||||||
|
@ -571,7 +544,6 @@ PyImaging_XbmEncoderNew(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)encoder;
|
return (PyObject *)encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* ZIP */
|
/* ZIP */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -581,8 +553,7 @@ PyImaging_XbmEncoderNew(PyObject* self, PyObject* args)
|
||||||
#include "libImaging/ZipCodecs.h"
|
#include "libImaging/ZipCodecs.h"
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -592,10 +563,16 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
|
||||||
Py_ssize_t compress_type = -1;
|
Py_ssize_t compress_type = -1;
|
||||||
char *dictionary = NULL;
|
char *dictionary = NULL;
|
||||||
Py_ssize_t dictionary_size = 0;
|
Py_ssize_t dictionary_size = 0;
|
||||||
if (!PyArg_ParseTuple(args, "ss|nnny#", &mode, &rawmode,
|
if (!PyArg_ParseTuple(
|
||||||
|
args,
|
||||||
|
"ss|nnny#",
|
||||||
|
&mode,
|
||||||
|
&rawmode,
|
||||||
&optimize,
|
&optimize,
|
||||||
&compress_level, &compress_type,
|
&compress_level,
|
||||||
&dictionary, &dictionary_size)) {
|
&compress_type,
|
||||||
|
&dictionary,
|
||||||
|
&dictionary_size)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +618,6 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* LibTiff */
|
/* LibTiff */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -653,8 +629,7 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -669,16 +644,24 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
int key_int, status, is_core_tag, is_var_length, num_core_tags, i;
|
int key_int, status, is_core_tag, is_var_length, num_core_tags, i;
|
||||||
TIFFDataType type = TIFF_NOTYPE;
|
TIFFDataType type = TIFF_NOTYPE;
|
||||||
// This list also exists in TiffTags.py
|
// This list also exists in TiffTags.py
|
||||||
const int core_tags[] = {
|
const int core_tags[] = {256, 257, 258, 259, 262, 263, 266, 269, 274,
|
||||||
256, 257, 258, 259, 262, 263, 266, 269, 274, 277, 278, 280, 281, 340,
|
277, 278, 280, 281, 340, 341, 282, 283, 284,
|
||||||
341, 282, 283, 284, 286, 287, 296, 297, 320, 321, 338, 32995, 32998, 32996,
|
286, 287, 296, 297, 320, 321, 338, 32995, 32998,
|
||||||
339, 32997, 330, 531, 530, 65537
|
32996, 339, 32997, 330, 531, 530, 65537};
|
||||||
};
|
|
||||||
|
|
||||||
Py_ssize_t tags_size;
|
Py_ssize_t tags_size;
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
|
|
||||||
if (! PyArg_ParseTuple(args, "sssnsOO", &mode, &rawmode, &compname, &fp, &filename, &tags, &types)) {
|
if (!PyArg_ParseTuple(
|
||||||
|
args,
|
||||||
|
"sssnsOO",
|
||||||
|
&mode,
|
||||||
|
&rawmode,
|
||||||
|
&compname,
|
||||||
|
&fp,
|
||||||
|
&filename,
|
||||||
|
&tags,
|
||||||
|
&types)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,7 +731,6 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (type == TIFF_NOTYPE) {
|
if (type == TIFF_NOTYPE) {
|
||||||
// Autodetect type. Types should not be changed for backwards
|
// Autodetect type. Types should not be changed for backwards
|
||||||
// compatibility.
|
// compatibility.
|
||||||
|
@ -787,15 +769,18 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
if (type == TIFF_BYTE) {
|
if (type == TIFF_BYTE) {
|
||||||
is_var_length = 1;
|
is_var_length = 1;
|
||||||
}
|
}
|
||||||
if (ImagingLibTiffMergeFieldInfo(&encoder->state, type, key_int, is_var_length)) {
|
if (ImagingLibTiffMergeFieldInfo(
|
||||||
|
&encoder->state, type, key_int, is_var_length)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TIFF_BYTE || type == TIFF_UNDEFINED) {
|
if (type == TIFF_BYTE || type == TIFF_UNDEFINED) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state,
|
||||||
(ttag_t)key_int,
|
(ttag_t)key_int,
|
||||||
PyBytes_Size(value), PyBytes_AsString(value));
|
PyBytes_Size(value),
|
||||||
|
PyBytes_AsString(value));
|
||||||
} else if (is_var_length) {
|
} else if (is_var_length) {
|
||||||
Py_ssize_t len, i;
|
Py_ssize_t len, i;
|
||||||
TRACE(("Setting from Tuple: %d \n", key_int));
|
TRACE(("Setting from Tuple: %d \n", key_int));
|
||||||
|
@ -804,7 +789,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
if (key_int == TIFFTAG_COLORMAP) {
|
if (key_int == TIFFTAG_COLORMAP) {
|
||||||
int stride = 256;
|
int stride = 256;
|
||||||
if (len != 768) {
|
if (len != 768) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Requiring 768 items for for Colormap");
|
PyErr_SetString(
|
||||||
|
PyExc_ValueError, "Requiring 768 items for for Colormap");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
UINT16 *av;
|
UINT16 *av;
|
||||||
|
@ -814,7 +800,9 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
av[i] = (UINT16)PyLong_AsLong(PyTuple_GetItem(value, i));
|
av[i] = (UINT16)PyLong_AsLong(PyTuple_GetItem(value, i));
|
||||||
}
|
}
|
||||||
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int,
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state,
|
||||||
|
(ttag_t)key_int,
|
||||||
av,
|
av,
|
||||||
av + stride,
|
av + stride,
|
||||||
av + stride * 2);
|
av + stride * 2);
|
||||||
|
@ -828,7 +816,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
av[i] = (UINT16)PyLong_AsLong(PyTuple_GetItem(value, i));
|
av[i] = (UINT16)PyLong_AsLong(PyTuple_GetItem(value, i));
|
||||||
}
|
}
|
||||||
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int, len, av);
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state, (ttag_t)key_int, len, av);
|
||||||
free(av);
|
free(av);
|
||||||
}
|
}
|
||||||
} else if (type == TIFF_LONG) {
|
} else if (type == TIFF_LONG) {
|
||||||
|
@ -839,7 +828,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
av[i] = (UINT32)PyLong_AsLong(PyTuple_GetItem(value, i));
|
av[i] = (UINT32)PyLong_AsLong(PyTuple_GetItem(value, i));
|
||||||
}
|
}
|
||||||
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int, len, av);
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state, (ttag_t)key_int, len, av);
|
||||||
free(av);
|
free(av);
|
||||||
}
|
}
|
||||||
} else if (type == TIFF_SBYTE) {
|
} else if (type == TIFF_SBYTE) {
|
||||||
|
@ -850,7 +840,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
av[i] = (INT8)PyLong_AsLong(PyTuple_GetItem(value, i));
|
av[i] = (INT8)PyLong_AsLong(PyTuple_GetItem(value, i));
|
||||||
}
|
}
|
||||||
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int, len, av);
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state, (ttag_t)key_int, len, av);
|
||||||
free(av);
|
free(av);
|
||||||
}
|
}
|
||||||
} else if (type == TIFF_SSHORT) {
|
} else if (type == TIFF_SSHORT) {
|
||||||
|
@ -861,7 +852,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
av[i] = (INT16)PyLong_AsLong(PyTuple_GetItem(value, i));
|
av[i] = (INT16)PyLong_AsLong(PyTuple_GetItem(value, i));
|
||||||
}
|
}
|
||||||
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int, len, av);
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state, (ttag_t)key_int, len, av);
|
||||||
free(av);
|
free(av);
|
||||||
}
|
}
|
||||||
} else if (type == TIFF_SLONG) {
|
} else if (type == TIFF_SLONG) {
|
||||||
|
@ -872,7 +864,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
av[i] = (INT32)PyLong_AsLong(PyTuple_GetItem(value, i));
|
av[i] = (INT32)PyLong_AsLong(PyTuple_GetItem(value, i));
|
||||||
}
|
}
|
||||||
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int, len, av);
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state, (ttag_t)key_int, len, av);
|
||||||
free(av);
|
free(av);
|
||||||
}
|
}
|
||||||
} else if (type == TIFF_FLOAT) {
|
} else if (type == TIFF_FLOAT) {
|
||||||
|
@ -883,7 +876,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
av[i] = (FLOAT32)PyFloat_AsDouble(PyTuple_GetItem(value, i));
|
av[i] = (FLOAT32)PyFloat_AsDouble(PyTuple_GetItem(value, i));
|
||||||
}
|
}
|
||||||
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int, len, av);
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state, (ttag_t)key_int, len, av);
|
||||||
free(av);
|
free(av);
|
||||||
}
|
}
|
||||||
} else if (type == TIFF_DOUBLE) {
|
} else if (type == TIFF_DOUBLE) {
|
||||||
|
@ -894,49 +888,42 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
av[i] = PyFloat_AsDouble(PyTuple_GetItem(value, i));
|
av[i] = PyFloat_AsDouble(PyTuple_GetItem(value, i));
|
||||||
}
|
}
|
||||||
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int, len, av);
|
status = ImagingLibTiffSetField(
|
||||||
|
&encoder->state, (ttag_t)key_int, len, av);
|
||||||
free(av);
|
free(av);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (type == TIFF_SHORT) {
|
if (type == TIFF_SHORT) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, (UINT16)PyLong_AsLong(value));
|
||||||
(UINT16)PyLong_AsLong(value));
|
|
||||||
} else if (type == TIFF_LONG) {
|
} else if (type == TIFF_LONG) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, (UINT32)PyLong_AsLong(value));
|
||||||
(UINT32)PyLong_AsLong(value));
|
|
||||||
} else if (type == TIFF_SSHORT) {
|
} else if (type == TIFF_SSHORT) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, (INT16)PyLong_AsLong(value));
|
||||||
(INT16)PyLong_AsLong(value));
|
|
||||||
} else if (type == TIFF_SLONG) {
|
} else if (type == TIFF_SLONG) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, (INT32)PyLong_AsLong(value));
|
||||||
(INT32)PyLong_AsLong(value));
|
|
||||||
} else if (type == TIFF_FLOAT) {
|
} else if (type == TIFF_FLOAT) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, (FLOAT32)PyFloat_AsDouble(value));
|
||||||
(FLOAT32)PyFloat_AsDouble(value));
|
|
||||||
} else if (type == TIFF_DOUBLE) {
|
} else if (type == TIFF_DOUBLE) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, (FLOAT64)PyFloat_AsDouble(value));
|
||||||
(FLOAT64)PyFloat_AsDouble(value));
|
|
||||||
} else if (type == TIFF_SBYTE) {
|
} else if (type == TIFF_SBYTE) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, (INT8)PyLong_AsLong(value));
|
||||||
(INT8)PyLong_AsLong(value));
|
|
||||||
} else if (type == TIFF_ASCII) {
|
} else if (type == TIFF_ASCII) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, PyBytes_AsString(value));
|
||||||
PyBytes_AsString(value));
|
|
||||||
} else if (type == TIFF_RATIONAL) {
|
} else if (type == TIFF_RATIONAL) {
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(
|
||||||
(ttag_t) key_int,
|
&encoder->state, (ttag_t)key_int, (FLOAT64)PyFloat_AsDouble(value));
|
||||||
(FLOAT64)PyFloat_AsDouble(value));
|
|
||||||
} else {
|
} else {
|
||||||
TRACE(("Unhandled type for key %d : %s \n",
|
TRACE(
|
||||||
|
("Unhandled type for key %d : %s \n",
|
||||||
key_int,
|
key_int,
|
||||||
PyBytes_AsString(PyObject_Str(value))));
|
PyBytes_AsString(PyObject_Str(value))));
|
||||||
}
|
}
|
||||||
|
@ -977,7 +964,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
#include "libImaging/Jpeg.h"
|
#include "libImaging/Jpeg.h"
|
||||||
|
|
||||||
static unsigned int* get_qtables_arrays(PyObject* qtables, int* qtablesLen) {
|
static unsigned int *
|
||||||
|
get_qtables_arrays(PyObject *qtables, int *qtablesLen) {
|
||||||
PyObject *tables;
|
PyObject *tables;
|
||||||
PyObject *table;
|
PyObject *table;
|
||||||
PyObject *table_data;
|
PyObject *table_data;
|
||||||
|
@ -996,7 +984,8 @@ static unsigned int* get_qtables_arrays(PyObject* qtables, int* qtablesLen) {
|
||||||
tables = PySequence_Fast(qtables, "expected a sequence");
|
tables = PySequence_Fast(qtables, "expected a sequence");
|
||||||
num_tables = PySequence_Size(qtables);
|
num_tables = PySequence_Size(qtables);
|
||||||
if (num_tables < 1 || num_tables > NUM_QUANT_TBLS) {
|
if (num_tables < 1 || num_tables > NUM_QUANT_TBLS) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(
|
||||||
|
PyExc_ValueError,
|
||||||
"Not a valid number of quantization tables. Should be between 1 and 4.");
|
"Not a valid number of quantization tables. Should be between 1 and 4.");
|
||||||
Py_DECREF(tables);
|
Py_DECREF(tables);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1019,7 +1008,8 @@ static unsigned int* get_qtables_arrays(PyObject* qtables, int* qtablesLen) {
|
||||||
}
|
}
|
||||||
table_data = PySequence_Fast(table, "expected a sequence");
|
table_data = PySequence_Fast(table, "expected a sequence");
|
||||||
for (j = 0; j < DCTSIZE2; j++) {
|
for (j = 0; j < DCTSIZE2; j++) {
|
||||||
qarrays[i * DCTSIZE2 + j] = PyLong_AS_LONG(PySequence_Fast_GET_ITEM(table_data, j));
|
qarrays[i * DCTSIZE2 + j] =
|
||||||
|
PyLong_AS_LONG(PySequence_Fast_GET_ITEM(table_data, j));
|
||||||
}
|
}
|
||||||
Py_DECREF(table_data);
|
Py_DECREF(table_data);
|
||||||
}
|
}
|
||||||
|
@ -1038,8 +1028,7 @@ JPEG_QTABLES_ERR:
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
|
|
||||||
char *mode;
|
char *mode;
|
||||||
|
@ -1059,11 +1048,24 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
||||||
char *rawExif = NULL;
|
char *rawExif = NULL;
|
||||||
Py_ssize_t rawExifLen = 0;
|
Py_ssize_t rawExifLen = 0;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ss|nnnnnnnnOy#y#",
|
if (!PyArg_ParseTuple(
|
||||||
&mode, &rawmode, &quality,
|
args,
|
||||||
&progressive, &smooth, &optimize, &streamtype,
|
"ss|nnnnnnnnOy#y#",
|
||||||
&xdpi, &ydpi, &subsampling, &qtables, &extra, &extra_size,
|
&mode,
|
||||||
&rawExif, &rawExifLen)) {
|
&rawmode,
|
||||||
|
&quality,
|
||||||
|
&progressive,
|
||||||
|
&smooth,
|
||||||
|
&optimize,
|
||||||
|
&streamtype,
|
||||||
|
&xdpi,
|
||||||
|
&ydpi,
|
||||||
|
&subsampling,
|
||||||
|
&qtables,
|
||||||
|
&extra,
|
||||||
|
&extra_size,
|
||||||
|
&rawExif,
|
||||||
|
&rawExifLen)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,7 +1139,6 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* JPEG 2000 */
|
/* JPEG 2000 */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -1147,8 +1148,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
||||||
#include "libImaging/Jpeg2K.h"
|
#include "libImaging/Jpeg2K.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_decode_coord_tuple(PyObject *tuple, int *x, int *y)
|
j2k_decode_coord_tuple(PyObject *tuple, int *x, int *y) {
|
||||||
{
|
|
||||||
*x = *y = 0;
|
*x = *y = 0;
|
||||||
|
|
||||||
if (tuple && PyTuple_Check(tuple) && PyTuple_GET_SIZE(tuple) == 2) {
|
if (tuple && PyTuple_Check(tuple) && PyTuple_GET_SIZE(tuple) == 2) {
|
||||||
|
@ -1165,8 +1165,7 @@ j2k_decode_coord_tuple(PyObject *tuple, int *x, int *y)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args)
|
PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
ImagingEncoderObject *encoder;
|
ImagingEncoderObject *encoder;
|
||||||
JPEG2KENCODESTATE *context;
|
JPEG2KENCODESTATE *context;
|
||||||
|
|
||||||
|
@ -1185,11 +1184,22 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args)
|
||||||
OPJ_CINEMA_MODE cine_mode;
|
OPJ_CINEMA_MODE cine_mode;
|
||||||
Py_ssize_t fd = -1;
|
Py_ssize_t fd = -1;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ss|OOOsOnOOOssn", &mode, &format,
|
if (!PyArg_ParseTuple(
|
||||||
&offset, &tile_offset, &tile_size,
|
args,
|
||||||
&quality_mode, &quality_layers, &num_resolutions,
|
"ss|OOOsOnOOOssn",
|
||||||
&cblk_size, &precinct_size,
|
&mode,
|
||||||
&irreversible, &progression, &cinema_mode,
|
&format,
|
||||||
|
&offset,
|
||||||
|
&tile_offset,
|
||||||
|
&tile_size,
|
||||||
|
&quality_mode,
|
||||||
|
&quality_layers,
|
||||||
|
&num_resolutions,
|
||||||
|
&cblk_size,
|
||||||
|
&precinct_size,
|
||||||
|
&irreversible,
|
||||||
|
&progression,
|
||||||
|
&cinema_mode,
|
||||||
&fd)) {
|
&fd)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1245,29 +1255,27 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args)
|
||||||
context->format = codec_format;
|
context->format = codec_format;
|
||||||
context->offset_x = context->offset_y = 0;
|
context->offset_x = context->offset_y = 0;
|
||||||
|
|
||||||
|
|
||||||
j2k_decode_coord_tuple(offset, &context->offset_x, &context->offset_y);
|
j2k_decode_coord_tuple(offset, &context->offset_x, &context->offset_y);
|
||||||
j2k_decode_coord_tuple(tile_offset,
|
j2k_decode_coord_tuple(
|
||||||
&context->tile_offset_x,
|
tile_offset, &context->tile_offset_x, &context->tile_offset_y);
|
||||||
&context->tile_offset_y);
|
j2k_decode_coord_tuple(tile_size, &context->tile_size_x, &context->tile_size_y);
|
||||||
j2k_decode_coord_tuple(tile_size,
|
|
||||||
&context->tile_size_x,
|
|
||||||
&context->tile_size_y);
|
|
||||||
|
|
||||||
/* Error on illegal tile offsets */
|
/* Error on illegal tile offsets */
|
||||||
if (context->tile_size_x && context->tile_size_y) {
|
if (context->tile_size_x && context->tile_size_y) {
|
||||||
if (context->tile_offset_x <= context->offset_x - context->tile_size_x
|
if (context->tile_offset_x <= context->offset_x - context->tile_size_x ||
|
||||||
|| context->tile_offset_y <= context->offset_y - context->tile_size_y) {
|
context->tile_offset_y <= context->offset_y - context->tile_size_y) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(
|
||||||
|
PyExc_ValueError,
|
||||||
"JPEG 2000 tile offset too small; top left tile must "
|
"JPEG 2000 tile offset too small; top left tile must "
|
||||||
"intersect image area");
|
"intersect image area");
|
||||||
Py_DECREF(encoder);
|
Py_DECREF(encoder);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->tile_offset_x > context->offset_x
|
if (context->tile_offset_x > context->offset_x ||
|
||||||
|| context->tile_offset_y > context->offset_y) {
|
context->tile_offset_y > context->offset_y) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(
|
||||||
|
PyExc_ValueError,
|
||||||
"JPEG 2000 tile offset too large to cover image area");
|
"JPEG 2000 tile offset too large to cover image area");
|
||||||
Py_DECREF(encoder);
|
Py_DECREF(encoder);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1282,12 +1290,9 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
context->num_resolutions = num_resolutions;
|
context->num_resolutions = num_resolutions;
|
||||||
|
|
||||||
j2k_decode_coord_tuple(cblk_size,
|
j2k_decode_coord_tuple(cblk_size, &context->cblk_width, &context->cblk_height);
|
||||||
&context->cblk_width,
|
j2k_decode_coord_tuple(
|
||||||
&context->cblk_height);
|
precinct_size, &context->precinct_width, &context->precinct_height);
|
||||||
j2k_decode_coord_tuple(precinct_size,
|
|
||||||
&context->precinct_width,
|
|
||||||
&context->precinct_height);
|
|
||||||
|
|
||||||
context->irreversible = PyObject_IsTrue(irreversible);
|
context->irreversible = PyObject_IsTrue(irreversible);
|
||||||
context->progression = prog_order;
|
context->progression = prog_order;
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
/* use Tests/make_hash.py to calculate these values */
|
/* use Tests/make_hash.py to calculate these values */
|
||||||
|
@ -19,8 +18,7 @@
|
||||||
static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE];
|
static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE];
|
||||||
|
|
||||||
static inline UINT32
|
static inline UINT32
|
||||||
hash(const char* mode)
|
hash(const char *mode) {
|
||||||
{
|
|
||||||
UINT32 i = ACCESS_TABLE_HASH;
|
UINT32 i = ACCESS_TABLE_HASH;
|
||||||
while (*mode) {
|
while (*mode) {
|
||||||
i = ((i << 5) + i) ^ (UINT8)*mode++;
|
i = ((i << 5) + i) ^ (UINT8)*mode++;
|
||||||
|
@ -29,13 +27,16 @@ hash(const char* mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImagingAccess
|
static ImagingAccess
|
||||||
add_item(const char* mode)
|
add_item(const char *mode) {
|
||||||
{
|
|
||||||
UINT32 i = hash(mode);
|
UINT32 i = hash(mode);
|
||||||
/* printf("hash %s => %d\n", mode, i); */
|
/* printf("hash %s => %d\n", mode, i); */
|
||||||
if (access_table[i].mode && strcmp(access_table[i].mode, mode) != 0) {
|
if (access_table[i].mode && strcmp(access_table[i].mode, mode) != 0) {
|
||||||
fprintf(stderr, "AccessInit: hash collision: %d for both %s and %s\n",
|
fprintf(
|
||||||
i, mode, access_table[i].mode);
|
stderr,
|
||||||
|
"AccessInit: hash collision: %d for both %s and %s\n",
|
||||||
|
i,
|
||||||
|
mode,
|
||||||
|
access_table[i].mode);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
access_table[i].mode = mode;
|
access_table[i].mode = mode;
|
||||||
|
@ -45,28 +46,24 @@ add_item(const char* mode)
|
||||||
/* fetch pointer to pixel line */
|
/* fetch pointer to pixel line */
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
line_8(Imaging im, int x, int y)
|
line_8(Imaging im, int x, int y) {
|
||||||
{
|
|
||||||
return &im->image8[y][x];
|
return &im->image8[y][x];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
line_16(Imaging im, int x, int y)
|
line_16(Imaging im, int x, int y) {
|
||||||
{
|
|
||||||
return &im->image8[y][x + x];
|
return &im->image8[y][x + x];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
line_32(Imaging im, int x, int y)
|
line_32(Imaging im, int x, int y) {
|
||||||
{
|
|
||||||
return &im->image32[y][x];
|
return &im->image32[y][x];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fetch individual pixel */
|
/* fetch individual pixel */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_pixel(Imaging im, int x, int y, void* color)
|
get_pixel(Imaging im, int x, int y, void *color) {
|
||||||
{
|
|
||||||
char *out = color;
|
char *out = color;
|
||||||
|
|
||||||
/* generic pixel access*/
|
/* generic pixel access*/
|
||||||
|
@ -85,15 +82,13 @@ get_pixel(Imaging im, int x, int y, void* color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_pixel_8(Imaging im, int x, int y, void* color)
|
get_pixel_8(Imaging im, int x, int y, void *color) {
|
||||||
{
|
|
||||||
char *out = color;
|
char *out = color;
|
||||||
out[0] = im->image8[y][x];
|
out[0] = im->image8[y][x];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_pixel_16L(Imaging im, int x, int y, void* color)
|
get_pixel_16L(Imaging im, int x, int y, void *color) {
|
||||||
{
|
|
||||||
UINT8 *in = (UINT8 *)&im->image[y][x + x];
|
UINT8 *in = (UINT8 *)&im->image[y][x + x];
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
UINT16 out = in[0] + (in[1] << 8);
|
UINT16 out = in[0] + (in[1] << 8);
|
||||||
|
@ -104,8 +99,7 @@ get_pixel_16L(Imaging im, int x, int y, void* color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_pixel_16B(Imaging im, int x, int y, void* color)
|
get_pixel_16B(Imaging im, int x, int y, void *color) {
|
||||||
{
|
|
||||||
UINT8 *in = (UINT8 *)&im->image[y][x + x];
|
UINT8 *in = (UINT8 *)&im->image[y][x + x];
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
memcpy(color, in, sizeof(UINT16));
|
memcpy(color, in, sizeof(UINT16));
|
||||||
|
@ -116,14 +110,12 @@ get_pixel_16B(Imaging im, int x, int y, void* color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_pixel_32(Imaging im, int x, int y, void* color)
|
get_pixel_32(Imaging im, int x, int y, void *color) {
|
||||||
{
|
|
||||||
memcpy(color, &im->image32[y][x], sizeof(INT32));
|
memcpy(color, &im->image32[y][x], sizeof(INT32));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_pixel_32L(Imaging im, int x, int y, void* color)
|
get_pixel_32L(Imaging im, int x, int y, void *color) {
|
||||||
{
|
|
||||||
UINT8 *in = (UINT8 *)&im->image[y][x * 4];
|
UINT8 *in = (UINT8 *)&im->image[y][x * 4];
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
INT32 out = in[0] + (in[1] << 8) + (in[2] << 16) + (in[3] << 24);
|
INT32 out = in[0] + (in[1] << 8) + (in[2] << 16) + (in[3] << 24);
|
||||||
|
@ -134,8 +126,7 @@ get_pixel_32L(Imaging im, int x, int y, void* color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_pixel_32B(Imaging im, int x, int y, void* color)
|
get_pixel_32B(Imaging im, int x, int y, void *color) {
|
||||||
{
|
|
||||||
UINT8 *in = (UINT8 *)&im->image[y][x * 4];
|
UINT8 *in = (UINT8 *)&im->image[y][x * 4];
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
memcpy(color, in, sizeof(INT32));
|
memcpy(color, in, sizeof(INT32));
|
||||||
|
@ -148,8 +139,7 @@ get_pixel_32B(Imaging im, int x, int y, void* color)
|
||||||
/* store individual pixel */
|
/* store individual pixel */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_pixel(Imaging im, int x, int y, const void* color)
|
put_pixel(Imaging im, int x, int y, const void *color) {
|
||||||
{
|
|
||||||
if (im->image8) {
|
if (im->image8) {
|
||||||
im->image8[y][x] = *((UINT8 *)color);
|
im->image8[y][x] = *((UINT8 *)color);
|
||||||
} else {
|
} else {
|
||||||
|
@ -158,20 +148,17 @@ put_pixel(Imaging im, int x, int y, const void* color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_pixel_8(Imaging im, int x, int y, const void* color)
|
put_pixel_8(Imaging im, int x, int y, const void *color) {
|
||||||
{
|
|
||||||
im->image8[y][x] = *((UINT8 *)color);
|
im->image8[y][x] = *((UINT8 *)color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_pixel_16L(Imaging im, int x, int y, const void* color)
|
put_pixel_16L(Imaging im, int x, int y, const void *color) {
|
||||||
{
|
|
||||||
memcpy(&im->image8[y][x + x], color, 2);
|
memcpy(&im->image8[y][x + x], color, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_pixel_16B(Imaging im, int x, int y, const void* color)
|
put_pixel_16B(Imaging im, int x, int y, const void *color) {
|
||||||
{
|
|
||||||
const char *in = color;
|
const char *in = color;
|
||||||
UINT8 *out = (UINT8 *)&im->image8[y][x + x];
|
UINT8 *out = (UINT8 *)&im->image8[y][x + x];
|
||||||
out[0] = in[1];
|
out[0] = in[1];
|
||||||
|
@ -179,14 +166,12 @@ put_pixel_16B(Imaging im, int x, int y, const void* color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_pixel_32L(Imaging im, int x, int y, const void* color)
|
put_pixel_32L(Imaging im, int x, int y, const void *color) {
|
||||||
{
|
|
||||||
memcpy(&im->image8[y][x * 4], color, 4);
|
memcpy(&im->image8[y][x * 4], color, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_pixel_32B(Imaging im, int x, int y, const void* color)
|
put_pixel_32B(Imaging im, int x, int y, const void *color) {
|
||||||
{
|
|
||||||
const char *in = color;
|
const char *in = color;
|
||||||
UINT8 *out = (UINT8 *)&im->image8[y][x * 4];
|
UINT8 *out = (UINT8 *)&im->image8[y][x * 4];
|
||||||
out[0] = in[3];
|
out[0] = in[3];
|
||||||
|
@ -196,16 +181,15 @@ put_pixel_32B(Imaging im, int x, int y, const void* color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_pixel_32(Imaging im, int x, int y, const void* color)
|
put_pixel_32(Imaging im, int x, int y, const void *color) {
|
||||||
{
|
|
||||||
memcpy(&im->image32[y][x], color, sizeof(INT32));
|
memcpy(&im->image32[y][x], color, sizeof(INT32));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingAccessInit()
|
ImagingAccessInit() {
|
||||||
{
|
|
||||||
#define ADD(mode_, line_, get_pixel_, put_pixel_) \
|
#define ADD(mode_, line_, get_pixel_, put_pixel_) \
|
||||||
{ ImagingAccess access = add_item(mode_); \
|
{ \
|
||||||
|
ImagingAccess access = add_item(mode_); \
|
||||||
access->line = line_; \
|
access->line = line_; \
|
||||||
access->get_pixel = get_pixel_; \
|
access->get_pixel = get_pixel_; \
|
||||||
access->put_pixel = put_pixel_; \
|
access->put_pixel = put_pixel_; \
|
||||||
|
@ -236,8 +220,7 @@ ImagingAccessInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingAccess
|
ImagingAccess
|
||||||
ImagingAccessNew(Imaging im)
|
ImagingAccessNew(Imaging im) {
|
||||||
{
|
|
||||||
ImagingAccess access = &access_table[hash(im->mode)];
|
ImagingAccess access = &access_table[hash(im->mode)];
|
||||||
if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0) {
|
if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -246,7 +229,4 @@ ImagingAccessNew(Imaging im)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_ImagingAccessDelete(Imaging im, ImagingAccess access)
|
_ImagingAccessDelete(Imaging im, ImagingAccess access) {}
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,39 +8,30 @@
|
||||||
* See the README file for details on usage and redistribution.
|
* See the README file for details on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#define PRECISION_BITS 7
|
#define PRECISION_BITS 7
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
UINT8 r;
|
UINT8 r;
|
||||||
UINT8 g;
|
UINT8 g;
|
||||||
UINT8 b;
|
UINT8 b;
|
||||||
UINT8 a;
|
UINT8 a;
|
||||||
} rgba8;
|
} rgba8;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingAlphaComposite(Imaging imDst, Imaging imSrc)
|
ImagingAlphaComposite(Imaging imDst, Imaging imSrc) {
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
if (!imDst || !imSrc ||
|
if (!imDst || !imSrc || strcmp(imDst->mode, "RGBA") ||
|
||||||
strcmp(imDst->mode, "RGBA") ||
|
imDst->type != IMAGING_TYPE_UINT8 || imDst->bands != 4) {
|
||||||
imDst->type != IMAGING_TYPE_UINT8 ||
|
|
||||||
imDst->bands != 4) {
|
|
||||||
return ImagingError_ModeError();
|
return ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(imDst->mode, imSrc->mode) ||
|
if (strcmp(imDst->mode, imSrc->mode) || imDst->type != imSrc->type ||
|
||||||
imDst->type != imSrc->type ||
|
imDst->bands != imSrc->bands || imDst->xsize != imSrc->xsize ||
|
||||||
imDst->bands != imSrc->bands ||
|
|
||||||
imDst->xsize != imSrc->xsize ||
|
|
||||||
imDst->ysize != imSrc->ysize) {
|
imDst->ysize != imSrc->ysize) {
|
||||||
return ImagingError_Mismatch();
|
return ImagingError_Mismatch();
|
||||||
}
|
}
|
||||||
|
@ -75,15 +66,19 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc)
|
||||||
tmpr = src->r * coef1 + dst->r * coef2;
|
tmpr = src->r * coef1 + dst->r * coef2;
|
||||||
tmpg = src->g * coef1 + dst->g * coef2;
|
tmpg = src->g * coef1 + dst->g * coef2;
|
||||||
tmpb = src->b * coef1 + dst->b * coef2;
|
tmpb = src->b * coef1 + dst->b * coef2;
|
||||||
out->r = SHIFTFORDIV255(tmpr + (0x80<<PRECISION_BITS)) >> PRECISION_BITS;
|
out->r =
|
||||||
out->g = SHIFTFORDIV255(tmpg + (0x80<<PRECISION_BITS)) >> PRECISION_BITS;
|
SHIFTFORDIV255(tmpr + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
|
||||||
out->b = SHIFTFORDIV255(tmpb + (0x80<<PRECISION_BITS)) >> PRECISION_BITS;
|
out->g =
|
||||||
|
SHIFTFORDIV255(tmpg + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
|
||||||
|
out->b =
|
||||||
|
SHIFTFORDIV255(tmpb + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
|
||||||
out->a = SHIFTFORDIV255(outa255 + 0x80);
|
out->a = SHIFTFORDIV255(outa255 + 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
dst++; src++; out++;
|
dst++;
|
||||||
|
src++;
|
||||||
|
out++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return imOut;
|
return imOut;
|
||||||
|
|
|
@ -15,13 +15,10 @@
|
||||||
* See the README file for details on usage and redistribution.
|
* See the README file for details on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingGetBand(Imaging imIn, int band)
|
ImagingGetBand(Imaging imIn, int band) {
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
@ -68,10 +65,8 @@ ImagingGetBand(Imaging imIn, int band)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingSplit(Imaging imIn, Imaging bands[4])
|
ImagingSplit(Imaging imIn, Imaging bands[4]) {
|
||||||
{
|
|
||||||
int i, j, x, y;
|
int i, j, x, y;
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
|
@ -171,10 +166,8 @@ ImagingSplit(Imaging imIn, Imaging bands[4])
|
||||||
return imIn->bands;
|
return imIn->bands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingPutBand(Imaging imOut, Imaging imIn, int band)
|
ImagingPutBand(Imaging imOut, Imaging imIn, int band) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
|
@ -186,8 +179,7 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band)
|
||||||
return (Imaging)ImagingError_ValueError("band index out of range");
|
return (Imaging)ImagingError_ValueError("band index out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imIn->type != imOut->type ||
|
if (imIn->type != imOut->type || imIn->xsize != imOut->xsize ||
|
||||||
imIn->xsize != imOut->xsize ||
|
|
||||||
imIn->ysize != imOut->ysize) {
|
imIn->ysize != imOut->ysize) {
|
||||||
return (Imaging)ImagingError_Mismatch();
|
return (Imaging)ImagingError_Mismatch();
|
||||||
}
|
}
|
||||||
|
@ -216,8 +208,7 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingFillBand(Imaging imOut, int band, int color)
|
ImagingFillBand(Imaging imOut, int band, int color) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
|
@ -249,8 +240,7 @@ ImagingFillBand(Imaging imOut, int band, int color)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingMerge(const char* mode, Imaging bands[4])
|
ImagingMerge(const char *mode, Imaging bands[4]) {
|
||||||
{
|
|
||||||
int i, x, y;
|
int i, x, y;
|
||||||
int bandsCount = 0;
|
int bandsCount = 0;
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
|
@ -268,8 +258,8 @@ ImagingMerge(const char* mode, Imaging bands[4])
|
||||||
if (bands[i]->bands != 1) {
|
if (bands[i]->bands != 1) {
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
if (bands[i]->xsize != firstBand->xsize
|
if (bands[i]->xsize != firstBand->xsize ||
|
||||||
|| bands[i]->ysize != firstBand->ysize) {
|
bands[i]->ysize != firstBand->ysize) {
|
||||||
return (Imaging)ImagingError_Mismatch();
|
return (Imaging)ImagingError_Mismatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,8 @@
|
||||||
* https://creativecommons.org/publicdomain/zero/1.0/
|
* https://creativecommons.org/publicdomain/zero/1.0/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT8 r, g, b, a;
|
UINT8 r, g, b, a;
|
||||||
} rgba;
|
} rgba;
|
||||||
|
@ -37,23 +35,24 @@ typedef struct {
|
||||||
UINT8 lut[6];
|
UINT8 lut[6];
|
||||||
} bc3_alpha;
|
} bc3_alpha;
|
||||||
|
|
||||||
#define LOAD16(p) \
|
#define LOAD16(p) (p)[0] | ((p)[1] << 8)
|
||||||
(p)[0] | ((p)[1] << 8)
|
|
||||||
|
|
||||||
#define LOAD32(p) \
|
#define LOAD32(p) (p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)
|
||||||
(p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)
|
|
||||||
|
|
||||||
static void bc1_color_load(bc1_color *dst, const UINT8 *src) {
|
static void
|
||||||
|
bc1_color_load(bc1_color *dst, const UINT8 *src) {
|
||||||
dst->c0 = LOAD16(src);
|
dst->c0 = LOAD16(src);
|
||||||
dst->c1 = LOAD16(src + 2);
|
dst->c1 = LOAD16(src + 2);
|
||||||
dst->lut = LOAD32(src + 4);
|
dst->lut = LOAD32(src + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bc3_alpha_load(bc3_alpha *dst, const UINT8 *src) {
|
static void
|
||||||
|
bc3_alpha_load(bc3_alpha *dst, const UINT8 *src) {
|
||||||
memcpy(dst, src, sizeof(bc3_alpha));
|
memcpy(dst, src, sizeof(bc3_alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
static rgba decode_565(UINT16 x) {
|
static rgba
|
||||||
|
decode_565(UINT16 x) {
|
||||||
rgba c;
|
rgba c;
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
r = (x & 0xf800) >> 8;
|
r = (x & 0xf800) >> 8;
|
||||||
|
@ -69,7 +68,8 @@ static rgba decode_565(UINT16 x) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc1_color(rgba *dst, const UINT8 *src) {
|
static void
|
||||||
|
decode_bc1_color(rgba *dst, const UINT8 *src) {
|
||||||
bc1_color col;
|
bc1_color col;
|
||||||
rgba p[4];
|
rgba p[4];
|
||||||
int n, cw;
|
int n, cw;
|
||||||
|
@ -109,7 +109,8 @@ static void decode_bc1_color(rgba *dst, const UINT8 *src) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc3_alpha(char *dst, const UINT8 *src, int stride, int o) {
|
static void
|
||||||
|
decode_bc3_alpha(char *dst, const UINT8 *src, int stride, int o) {
|
||||||
bc3_alpha b;
|
bc3_alpha b;
|
||||||
UINT16 a0, a1;
|
UINT16 a0, a1;
|
||||||
UINT8 a[8];
|
UINT8 a[8];
|
||||||
|
@ -147,11 +148,13 @@ static void decode_bc3_alpha(char *dst, const UINT8 *src, int stride, int o) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc1_block(rgba *col, const UINT8* src) {
|
static void
|
||||||
|
decode_bc1_block(rgba *col, const UINT8 *src) {
|
||||||
decode_bc1_color(col, src);
|
decode_bc1_color(col, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc2_block(rgba *col, const UINT8* src) {
|
static void
|
||||||
|
decode_bc2_block(rgba *col, const UINT8 *src) {
|
||||||
int n, bitI, byI, av;
|
int n, bitI, byI, av;
|
||||||
decode_bc1_color(col, src + 8);
|
decode_bc1_color(col, src + 8);
|
||||||
for (n = 0; n < 16; n++) {
|
for (n = 0; n < 16; n++) {
|
||||||
|
@ -163,30 +166,36 @@ static void decode_bc2_block(rgba *col, const UINT8* src) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc3_block(rgba *col, const UINT8* src) {
|
static void
|
||||||
|
decode_bc3_block(rgba *col, const UINT8 *src) {
|
||||||
decode_bc1_color(col, src + 8);
|
decode_bc1_color(col, src + 8);
|
||||||
decode_bc3_alpha((char *)col, src, sizeof(col[0]), 3);
|
decode_bc3_alpha((char *)col, src, sizeof(col[0]), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc4_block(lum *col, const UINT8* src) {
|
static void
|
||||||
|
decode_bc4_block(lum *col, const UINT8 *src) {
|
||||||
decode_bc3_alpha((char *)col, src, sizeof(col[0]), 0);
|
decode_bc3_alpha((char *)col, src, sizeof(col[0]), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc5_block(rgba *col, const UINT8* src) {
|
static void
|
||||||
|
decode_bc5_block(rgba *col, const UINT8 *src) {
|
||||||
decode_bc3_alpha((char *)col, src, sizeof(col[0]), 0);
|
decode_bc3_alpha((char *)col, src, sizeof(col[0]), 0);
|
||||||
decode_bc3_alpha((char *)col, src + 8, sizeof(col[0]), 1);
|
decode_bc3_alpha((char *)col, src + 8, sizeof(col[0]), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BC6 and BC7 are described here:
|
/* BC6 and BC7 are described here:
|
||||||
https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_bptc.txt */
|
https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_bptc.txt
|
||||||
|
*/
|
||||||
|
|
||||||
static UINT8 get_bit(const UINT8* src, int bit) {
|
static UINT8
|
||||||
|
get_bit(const UINT8 *src, int bit) {
|
||||||
int by = bit >> 3;
|
int by = bit >> 3;
|
||||||
bit &= 7;
|
bit &= 7;
|
||||||
return (src[by] >> bit) & 1;
|
return (src[by] >> bit) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT8 get_bits(const UINT8* src, int bit, int count) {
|
static UINT8
|
||||||
|
get_bits(const UINT8 *src, int bit, int count) {
|
||||||
UINT8 v;
|
UINT8 v;
|
||||||
int x;
|
int x;
|
||||||
int by = bit >> 3;
|
int by = bit >> 3;
|
||||||
|
@ -225,73 +234,51 @@ static const bc7_mode_info bc7_modes[] = {
|
||||||
{1, 0, 2, 1, 5, 6, 0, 0, 2, 3},
|
{1, 0, 2, 1, 5, 6, 0, 0, 2, 3},
|
||||||
{1, 0, 2, 0, 7, 8, 0, 0, 2, 2},
|
{1, 0, 2, 0, 7, 8, 0, 0, 2, 2},
|
||||||
{1, 0, 0, 0, 7, 7, 1, 0, 4, 0},
|
{1, 0, 0, 0, 7, 7, 1, 0, 4, 0},
|
||||||
{2, 6, 0, 0, 5, 5, 1, 0, 2, 0}
|
{2, 6, 0, 0, 5, 5, 1, 0, 2, 0}};
|
||||||
};
|
|
||||||
|
|
||||||
/* Subset indices:
|
/* Subset indices:
|
||||||
Table.P2, 1 bit per index */
|
Table.P2, 1 bit per index */
|
||||||
static const UINT16 bc7_si2[] = {
|
static const UINT16 bc7_si2[] = {
|
||||||
0xcccc, 0x8888, 0xeeee, 0xecc8, 0xc880, 0xfeec, 0xfec8, 0xec80,
|
0xcccc, 0x8888, 0xeeee, 0xecc8, 0xc880, 0xfeec, 0xfec8, 0xec80, 0xc800, 0xffec,
|
||||||
0xc800, 0xffec, 0xfe80, 0xe800, 0xffe8, 0xff00, 0xfff0, 0xf000,
|
0xfe80, 0xe800, 0xffe8, 0xff00, 0xfff0, 0xf000, 0xf710, 0x008e, 0x7100, 0x08ce,
|
||||||
0xf710, 0x008e, 0x7100, 0x08ce, 0x008c, 0x7310, 0x3100, 0x8cce,
|
0x008c, 0x7310, 0x3100, 0x8cce, 0x088c, 0x3110, 0x6666, 0x366c, 0x17e8, 0x0ff0,
|
||||||
0x088c, 0x3110, 0x6666, 0x366c, 0x17e8, 0x0ff0, 0x718e, 0x399c,
|
0x718e, 0x399c, 0xaaaa, 0xf0f0, 0x5a5a, 0x33cc, 0x3c3c, 0x55aa, 0x9696, 0xa55a,
|
||||||
0xaaaa, 0xf0f0, 0x5a5a, 0x33cc, 0x3c3c, 0x55aa, 0x9696, 0xa55a,
|
0x73ce, 0x13c8, 0x324c, 0x3bdc, 0x6996, 0xc33c, 0x9966, 0x0660, 0x0272, 0x04e4,
|
||||||
0x73ce, 0x13c8, 0x324c, 0x3bdc, 0x6996, 0xc33c, 0x9966, 0x0660,
|
0x4e40, 0x2720, 0xc936, 0x936c, 0x39c6, 0x639c, 0x9336, 0x9cc6, 0x817e, 0xe718,
|
||||||
0x0272, 0x04e4, 0x4e40, 0x2720, 0xc936, 0x936c, 0x39c6, 0x639c,
|
0xccf0, 0x0fcc, 0x7744, 0xee22};
|
||||||
0x9336, 0x9cc6, 0x817e, 0xe718, 0xccf0, 0x0fcc, 0x7744, 0xee22};
|
|
||||||
|
|
||||||
/* Table.P3, 2 bits per index */
|
/* Table.P3, 2 bits per index */
|
||||||
static const UINT32 bc7_si3[] = {
|
static const UINT32 bc7_si3[] = {
|
||||||
0xaa685050, 0x6a5a5040, 0x5a5a4200, 0x5450a0a8,
|
0xaa685050, 0x6a5a5040, 0x5a5a4200, 0x5450a0a8, 0xa5a50000, 0xa0a05050, 0x5555a0a0,
|
||||||
0xa5a50000, 0xa0a05050, 0x5555a0a0, 0x5a5a5050,
|
0x5a5a5050, 0xaa550000, 0xaa555500, 0xaaaa5500, 0x90909090, 0x94949494, 0xa4a4a4a4,
|
||||||
0xaa550000, 0xaa555500, 0xaaaa5500, 0x90909090,
|
0xa9a59450, 0x2a0a4250, 0xa5945040, 0x0a425054, 0xa5a5a500, 0x55a0a0a0, 0xa8a85454,
|
||||||
0x94949494, 0xa4a4a4a4, 0xa9a59450, 0x2a0a4250,
|
0x6a6a4040, 0xa4a45000, 0x1a1a0500, 0x0050a4a4, 0xaaa59090, 0x14696914, 0x69691400,
|
||||||
0xa5945040, 0x0a425054, 0xa5a5a500, 0x55a0a0a0,
|
0xa08585a0, 0xaa821414, 0x50a4a450, 0x6a5a0200, 0xa9a58000, 0x5090a0a8, 0xa8a09050,
|
||||||
0xa8a85454, 0x6a6a4040, 0xa4a45000, 0x1a1a0500,
|
0x24242424, 0x00aa5500, 0x24924924, 0x24499224, 0x50a50a50, 0x500aa550, 0xaaaa4444,
|
||||||
0x0050a4a4, 0xaaa59090, 0x14696914, 0x69691400,
|
0x66660000, 0xa5a0a5a0, 0x50a050a0, 0x69286928, 0x44aaaa44, 0x66666600, 0xaa444444,
|
||||||
0xa08585a0, 0xaa821414, 0x50a4a450, 0x6a5a0200,
|
0x54a854a8, 0x95809580, 0x96969600, 0xa85454a8, 0x80959580, 0xaa141414, 0x96960000,
|
||||||
0xa9a58000, 0x5090a0a8, 0xa8a09050, 0x24242424,
|
0xaaaa1414, 0xa05050a0, 0xa0a5a5a0, 0x96000000, 0x40804080, 0xa9a8a9a8, 0xaaaaaa44,
|
||||||
0x00aa5500, 0x24924924, 0x24499224, 0x50a50a50,
|
0x2a4a5254};
|
||||||
0x500aa550, 0xaaaa4444, 0x66660000, 0xa5a0a5a0,
|
|
||||||
0x50a050a0, 0x69286928, 0x44aaaa44, 0x66666600,
|
|
||||||
0xaa444444, 0x54a854a8, 0x95809580, 0x96969600,
|
|
||||||
0xa85454a8, 0x80959580, 0xaa141414, 0x96960000,
|
|
||||||
0xaaaa1414, 0xa05050a0, 0xa0a5a5a0, 0x96000000,
|
|
||||||
0x40804080, 0xa9a8a9a8, 0xaaaaaa44, 0x2a4a5254};
|
|
||||||
|
|
||||||
/* Anchor indices:
|
/* Anchor indices:
|
||||||
Table.A2 */
|
Table.A2 */
|
||||||
static const char bc7_ai0[] = {
|
static const char bc7_ai0[] = {
|
||||||
15,15,15,15,15,15,15,15,
|
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 8, 2, 2, 8,
|
||||||
15,15,15,15,15,15,15,15,
|
8, 15, 2, 8, 2, 2, 8, 8, 2, 2, 15, 15, 6, 8, 2, 8, 15, 15, 2, 8, 2, 2,
|
||||||
15, 2, 8, 2, 2, 8, 8,15,
|
2, 15, 15, 6, 6, 2, 6, 8, 15, 15, 2, 2, 15, 15, 15, 15, 15, 2, 2, 15};
|
||||||
2, 8, 2, 2, 8, 8, 2, 2,
|
|
||||||
15,15, 6, 8, 2, 8,15,15,
|
|
||||||
2, 8, 2, 2, 2,15,15, 6,
|
|
||||||
6, 2, 6, 8,15,15, 2, 2,
|
|
||||||
15,15,15,15,15, 2, 2,15};
|
|
||||||
|
|
||||||
/* Table.A3a */
|
/* Table.A3a */
|
||||||
static const char bc7_ai1[] = {
|
static const char bc7_ai1[] = {
|
||||||
3, 3,15,15, 8, 3,15,15,
|
3, 3, 15, 15, 8, 3, 15, 15, 8, 8, 6, 6, 6, 5, 3, 3, 3, 3, 8, 15, 3, 3,
|
||||||
8, 8, 6, 6, 6, 5, 3, 3,
|
6, 10, 5, 8, 8, 6, 8, 5, 15, 15, 8, 15, 3, 5, 6, 10, 8, 15, 15, 3, 15, 5,
|
||||||
3, 3, 8,15, 3, 3, 6,10,
|
15, 15, 15, 15, 3, 15, 5, 5, 5, 8, 5, 10, 5, 10, 8, 13, 15, 12, 3, 3};
|
||||||
5, 8, 8, 6, 8, 5,15,15,
|
|
||||||
8,15, 3, 5, 6,10, 8,15,
|
|
||||||
15, 3,15, 5,15,15,15,15,
|
|
||||||
3,15, 5, 5, 5, 8, 5,10,
|
|
||||||
5,10, 8,13,15,12, 3, 3};
|
|
||||||
|
|
||||||
/* Table.A3b */
|
/* Table.A3b */
|
||||||
static const char bc7_ai2[] = {
|
static const char bc7_ai2[] = {15, 8, 8, 3, 15, 15, 3, 8, 15, 15, 15, 15, 15,
|
||||||
15, 8, 8, 3,15,15, 3, 8,
|
15, 15, 8, 15, 8, 15, 3, 15, 8, 15, 8, 3, 15,
|
||||||
15,15,15,15,15,15,15, 8,
|
6, 10, 15, 15, 10, 8, 15, 3, 15, 10, 10, 8, 9,
|
||||||
15, 8,15, 3,15, 8,15, 8,
|
10, 6, 15, 8, 15, 3, 6, 6, 8, 15, 3, 15, 15,
|
||||||
3,15, 6,10,15,15,10, 8,
|
15, 15, 15, 15, 15, 15, 15, 15, 3, 15, 15, 8};
|
||||||
15, 3,15,10,10, 8, 9,10,
|
|
||||||
6,15, 8,15, 3, 6, 6, 8,
|
|
||||||
15, 3,15,15,15,15,15,15,
|
|
||||||
15,15,15,15, 3,15,15, 8};
|
|
||||||
|
|
||||||
/* Interpolation weights */
|
/* Interpolation weights */
|
||||||
static const char bc7_weights2[] = {0, 21, 43, 64};
|
static const char bc7_weights2[] = {0, 21, 43, 64};
|
||||||
|
@ -299,7 +286,8 @@ static const char bc7_weights3[] = {0, 9, 18, 27, 37, 46, 55, 64};
|
||||||
static const char bc7_weights4[] = {
|
static const char bc7_weights4[] = {
|
||||||
0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64};
|
0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64};
|
||||||
|
|
||||||
static const char *bc7_get_weights(int n) {
|
static const char *
|
||||||
|
bc7_get_weights(int n) {
|
||||||
if (n == 2) {
|
if (n == 2) {
|
||||||
return bc7_weights2;
|
return bc7_weights2;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +297,8 @@ static const char *bc7_get_weights(int n) {
|
||||||
return bc7_weights4;
|
return bc7_weights4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bc7_get_subset(int ns, int partition, int n) {
|
static int
|
||||||
|
bc7_get_subset(int ns, int partition, int n) {
|
||||||
if (ns == 2) {
|
if (ns == 2) {
|
||||||
return 1 & (bc7_si2[partition] >> n);
|
return 1 & (bc7_si2[partition] >> n);
|
||||||
}
|
}
|
||||||
|
@ -319,12 +308,14 @@ static int bc7_get_subset(int ns, int partition, int n) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT8 expand_quantized(UINT8 v, int bits) {
|
static UINT8
|
||||||
|
expand_quantized(UINT8 v, int bits) {
|
||||||
v = v << (8 - bits);
|
v = v << (8 - bits);
|
||||||
return v | (v >> bits);
|
return v | (v >> bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bc7_lerp(rgba *dst, const rgba *e, int s0, int s1) {
|
static void
|
||||||
|
bc7_lerp(rgba *dst, const rgba *e, int s0, int s1) {
|
||||||
int t0 = 64 - s0;
|
int t0 = 64 - s0;
|
||||||
int t1 = 64 - s1;
|
int t1 = 64 - s1;
|
||||||
dst->r = (UINT8)((t0 * e[0].r + s0 * e[1].r + 32) >> 6);
|
dst->r = (UINT8)((t0 * e[0].r + s0 * e[1].r + 32) >> 6);
|
||||||
|
@ -333,7 +324,8 @@ static void bc7_lerp(rgba *dst, const rgba *e, int s0, int s1) {
|
||||||
dst->a = (UINT8)((t1 * e[0].a + s1 * e[1].a + 32) >> 6);
|
dst->a = (UINT8)((t1 * e[0].a + s1 * e[1].a + 32) >> 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc7_block(rgba *col, const UINT8* src) {
|
static void
|
||||||
|
decode_bc7_block(rgba *col, const UINT8 *src) {
|
||||||
rgba endpoints[6];
|
rgba endpoints[6];
|
||||||
int bit = 0, cibit, aibit;
|
int bit = 0, cibit, aibit;
|
||||||
int mode = src[0];
|
int mode = src[0];
|
||||||
|
@ -352,7 +344,8 @@ static void decode_bc7_block(rgba *col, const UINT8* src) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (!(mode & (1 << bit++))) ;
|
while (!(mode & (1 << bit++)))
|
||||||
|
;
|
||||||
mode = bit - 1;
|
mode = bit - 1;
|
||||||
info = &bc7_modes[mode];
|
info = &bc7_modes[mode];
|
||||||
/* color selection bits: {subset}{endpoint} */
|
/* color selection bits: {subset}{endpoint} */
|
||||||
|
@ -525,79 +518,75 @@ static const bc6_mode_info bc6_modes[] = {
|
||||||
{1, 0, 0, 10, 10, 10, 10},
|
{1, 0, 0, 10, 10, 10, 10},
|
||||||
{1, 1, 0, 11, 9, 9, 9},
|
{1, 1, 0, 11, 9, 9, 9},
|
||||||
{1, 1, 0, 12, 8, 8, 8},
|
{1, 1, 0, 12, 8, 8, 8},
|
||||||
{1, 1, 0, 16, 4, 4, 4}
|
{1, 1, 0, 16, 4, 4, 4}};
|
||||||
};
|
|
||||||
|
|
||||||
/* Table.F, encoded as a sequence of bit indices */
|
/* Table.F, encoded as a sequence of bit indices */
|
||||||
static const UINT8 bc6_bit_packings[][75] = {
|
static const UINT8 bc6_bit_packings[][75] = {
|
||||||
{116, 132, 176, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22,
|
{116, 132, 176, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17,
|
||||||
23, 24, 25, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52,
|
18, 19, 20, 21, 22, 23, 24, 25, 32, 33, 34, 35, 36, 37, 38,
|
||||||
164, 112, 113, 114, 115, 64, 65, 66, 67, 68, 172, 160, 161, 162, 163, 80,
|
39, 40, 41, 48, 49, 50, 51, 52, 164, 112, 113, 114, 115, 64, 65,
|
||||||
81, 82, 83, 84, 173, 128, 129, 130, 131, 96, 97, 98, 99, 100, 174, 144,
|
66, 67, 68, 172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 173, 128,
|
||||||
145, 146, 147, 148, 175},
|
129, 130, 131, 96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||||
{117, 164, 165, 0, 1, 2, 3, 4, 5, 6, 172, 173, 132, 16, 17, 18, 19, 20, 21,
|
{117, 164, 165, 0, 1, 2, 3, 4, 5, 6, 172, 173, 132, 16, 17,
|
||||||
22, 133, 174, 116, 32, 33, 34, 35, 36, 37, 38, 175, 177, 176, 48, 49, 50,
|
18, 19, 20, 21, 22, 133, 174, 116, 32, 33, 34, 35, 36, 37, 38,
|
||||||
51, 52, 53, 112, 113, 114, 115, 64, 65, 66, 67, 68, 69, 160, 161, 162, 163,
|
175, 177, 176, 48, 49, 50, 51, 52, 53, 112, 113, 114, 115, 64, 65,
|
||||||
80, 81, 82, 83, 84, 85, 128, 129, 130, 131, 96, 97, 98, 99, 100, 101, 144,
|
66, 67, 68, 69, 160, 161, 162, 163, 80, 81, 82, 83, 84, 85, 128,
|
||||||
145, 146, 147, 148, 149},
|
129, 130, 131, 96, 97, 98, 99, 100, 101, 144, 145, 146, 147, 148, 149},
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20,
|
||||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 10, 112, 113, 114,
|
21, 22, 23, 24, 25, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
|
||||||
115, 64, 65, 66, 67, 26, 172, 160, 161, 162, 163, 80, 81, 82, 83, 42, 173,
|
48, 49, 50, 51, 52, 10, 112, 113, 114, 115, 64, 65, 66, 67, 26,
|
||||||
128, 129, 130, 131, 96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148,
|
172, 160, 161, 162, 163, 80, 81, 82, 83, 42, 173, 128, 129, 130, 131,
|
||||||
175},
|
96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20,
|
||||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 10, 164, 112, 113, 114,
|
21, 22, 23, 24, 25, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
|
||||||
115, 64, 65, 66, 67, 68, 26, 160, 161, 162, 163, 80, 81, 82, 83, 42, 173,
|
48, 49, 50, 51, 10, 164, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||||
128, 129, 130, 131, 96, 97, 98, 99, 172, 174, 144, 145, 146, 147, 116,
|
26, 160, 161, 162, 163, 80, 81, 82, 83, 42, 173, 128, 129, 130, 131,
|
||||||
175},
|
96, 97, 98, 99, 172, 174, 144, 145, 146, 147, 116, 175},
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20,
|
||||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 10, 132, 112, 113, 114,
|
21, 22, 23, 24, 25, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
|
||||||
115, 64, 65, 66, 67, 26, 172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 42,
|
48, 49, 50, 51, 10, 132, 112, 113, 114, 115, 64, 65, 66, 67, 26,
|
||||||
128, 129, 130, 131, 96, 97, 98, 99, 173, 174, 144, 145, 146, 147, 176,
|
172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 42, 128, 129, 130, 131,
|
||||||
175},
|
96, 97, 98, 99, 173, 174, 144, 145, 146, 147, 176, 175},
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 132, 16, 17, 18, 19, 20, 21, 22, 23, 24, 116,
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 132, 16, 17, 18, 19, 20,
|
||||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 176, 48, 49, 50, 51, 52, 164, 112, 113,
|
21, 22, 23, 24, 116, 32, 33, 34, 35, 36, 37, 38, 39, 40, 176,
|
||||||
114, 115, 64, 65, 66, 67, 68, 172, 160, 161, 162, 163, 80, 81, 82, 83, 84,
|
48, 49, 50, 51, 52, 164, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||||
173, 128, 129, 130, 131, 96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148,
|
172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 173, 128, 129, 130, 131,
|
||||||
175},
|
96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 164, 132, 16, 17, 18, 19, 20, 21, 22, 23, 174, 116,
|
{0, 1, 2, 3, 4, 5, 6, 7, 164, 132, 16, 17, 18, 19, 20,
|
||||||
32, 33, 34, 35, 36, 37, 38, 39, 175, 176, 48, 49, 50, 51, 52, 53, 112, 113,
|
21, 22, 23, 174, 116, 32, 33, 34, 35, 36, 37, 38, 39, 175, 176,
|
||||||
114, 115, 64, 65, 66, 67, 68, 172, 160, 161, 162, 163, 80, 81, 82, 83, 84,
|
48, 49, 50, 51, 52, 53, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||||
173, 128, 129, 130, 131, 96, 97, 98, 99, 100, 101, 144, 145, 146, 147, 148,
|
172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 173, 128, 129, 130, 131,
|
||||||
149},
|
96, 97, 98, 99, 100, 101, 144, 145, 146, 147, 148, 149},
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 172, 132, 16, 17, 18, 19, 20, 21, 22, 23, 117, 116,
|
{0, 1, 2, 3, 4, 5, 6, 7, 172, 132, 16, 17, 18, 19, 20,
|
||||||
32, 33, 34, 35, 36, 37, 38, 39, 165, 176, 48, 49, 50, 51, 52, 164, 112,
|
21, 22, 23, 117, 116, 32, 33, 34, 35, 36, 37, 38, 39, 165, 176,
|
||||||
113, 114, 115, 64, 65, 66, 67, 68, 69, 160, 161, 162, 163, 80, 81, 82, 83,
|
48, 49, 50, 51, 52, 164, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||||
84, 173, 128, 129, 130, 131, 96, 97, 98, 99, 100, 174, 144, 145, 146, 147,
|
69, 160, 161, 162, 163, 80, 81, 82, 83, 84, 173, 128, 129, 130, 131,
|
||||||
148, 175},
|
96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 173, 132, 16, 17, 18, 19, 20, 21, 22, 23, 133, 116,
|
{0, 1, 2, 3, 4, 5, 6, 7, 173, 132, 16, 17, 18, 19, 20,
|
||||||
32, 33, 34, 35, 36, 37, 38, 39, 177, 176, 48, 49, 50, 51, 52, 164, 112,
|
21, 22, 23, 133, 116, 32, 33, 34, 35, 36, 37, 38, 39, 177, 176,
|
||||||
113, 114, 115, 64, 65, 66, 67, 68, 172, 160, 161, 162, 163, 80, 81, 82, 83,
|
48, 49, 50, 51, 52, 164, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||||
84, 85, 128, 129, 130, 131, 96, 97, 98, 99, 100, 174, 144, 145, 146, 147,
|
172, 160, 161, 162, 163, 80, 81, 82, 83, 84, 85, 128, 129, 130, 131,
|
||||||
148, 175},
|
96, 97, 98, 99, 100, 174, 144, 145, 146, 147, 148, 175},
|
||||||
{0, 1, 2, 3, 4, 5, 164, 172, 173, 132, 16, 17, 18, 19, 20, 21, 117, 133,
|
{0, 1, 2, 3, 4, 5, 164, 172, 173, 132, 16, 17, 18, 19, 20,
|
||||||
174, 116, 32, 33, 34, 35, 36, 37, 165, 175, 177, 176, 48, 49, 50, 51, 52,
|
21, 117, 133, 174, 116, 32, 33, 34, 35, 36, 37, 165, 175, 177, 176,
|
||||||
53, 112, 113, 114, 115, 64, 65, 66, 67, 68, 69, 160, 161, 162, 163, 80, 81,
|
48, 49, 50, 51, 52, 53, 112, 113, 114, 115, 64, 65, 66, 67, 68,
|
||||||
82, 83, 84, 85, 128, 129, 130, 131, 96, 97, 98, 99, 100, 101, 144, 145,
|
69, 160, 161, 162, 163, 80, 81, 82, 83, 84, 85, 128, 129, 130, 131,
|
||||||
146, 147, 148, 149},
|
96, 97, 98, 99, 100, 101, 144, 145, 146, 147, 148, 149},
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
|
||||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 80, 81, 82, 83, 84, 85, 86, 87, 88,
|
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89},
|
||||||
89},
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 10,
|
||||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 10,
|
64, 65, 66, 67, 68, 69, 70, 71, 72, 26, 80, 81, 82, 83, 84, 85, 86, 87, 88, 42},
|
||||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 26, 80, 81, 82, 83, 84, 85, 86, 87, 88,
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||||
42},
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 11, 10,
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
|
64, 65, 66, 67, 68, 69, 70, 71, 27, 26, 80, 81, 82, 83, 84, 85, 86, 87, 43, 42},
|
||||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 11, 10,
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||||
64, 65, 66, 67, 68, 69, 70, 71, 27, 26, 80, 81, 82, 83, 84, 85, 86, 87, 43,
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 15, 14, 13, 12, 11, 10,
|
||||||
42},
|
64, 65, 66, 67, 31, 30, 29, 28, 27, 26, 80, 81, 82, 83, 47, 46, 45, 44, 43, 42}};
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
|
|
||||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 15, 14, 13, 12, 11, 10,
|
|
||||||
64, 65, 66, 67, 31, 30, 29, 28, 27, 26, 80, 81, 82, 83, 47, 46, 45, 44, 43,
|
|
||||||
42}};
|
|
||||||
|
|
||||||
static void bc6_sign_extend(UINT16 *v, int prec) {
|
static void
|
||||||
|
bc6_sign_extend(UINT16 *v, int prec) {
|
||||||
int x = *v;
|
int x = *v;
|
||||||
if (x & (1 << (prec - 1))) {
|
if (x & (1 << (prec - 1))) {
|
||||||
x |= -1 << prec;
|
x |= -1 << prec;
|
||||||
|
@ -605,7 +594,8 @@ static void bc6_sign_extend(UINT16 *v, int prec) {
|
||||||
*v = (UINT16)x;
|
*v = (UINT16)x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bc6_unquantize(UINT16 v, int prec, int sign) {
|
static int
|
||||||
|
bc6_unquantize(UINT16 v, int prec, int sign) {
|
||||||
int s = 0;
|
int s = 0;
|
||||||
int x;
|
int x;
|
||||||
if (!sign) {
|
if (!sign) {
|
||||||
|
@ -645,7 +635,8 @@ static int bc6_unquantize(UINT16 v, int prec, int sign) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float half_to_float(UINT16 h) {
|
static float
|
||||||
|
half_to_float(UINT16 h) {
|
||||||
/* https://gist.github.com/rygorous/2144712 */
|
/* https://gist.github.com/rygorous/2144712 */
|
||||||
union {
|
union {
|
||||||
UINT32 u;
|
UINT32 u;
|
||||||
|
@ -662,7 +653,8 @@ static float half_to_float(UINT16 h) {
|
||||||
return o.f;
|
return o.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float bc6_finalize(int v, int sign) {
|
static float
|
||||||
|
bc6_finalize(int v, int sign) {
|
||||||
if (sign) {
|
if (sign) {
|
||||||
if (v < 0) {
|
if (v < 0) {
|
||||||
v = ((-v) * 31) / 32;
|
v = ((-v) * 31) / 32;
|
||||||
|
@ -675,7 +667,8 @@ static float bc6_finalize(int v, int sign) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bc6_lerp(rgb32f *col, int *e0, int *e1, int s, int sign) {
|
static void
|
||||||
|
bc6_lerp(rgb32f *col, int *e0, int *e1, int s, int sign) {
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
int t = 64 - s;
|
int t = 64 - s;
|
||||||
r = (e0[0] * t + e1[0] * s) >> 6;
|
r = (e0[0] * t + e1[0] * s) >> 6;
|
||||||
|
@ -686,7 +679,8 @@ static void bc6_lerp(rgb32f *col, int *e0, int *e1, int s, int sign) {
|
||||||
col->b = bc6_finalize(b, sign);
|
col->b = bc6_finalize(b, sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_bc6_block(rgb32f *col, const UINT8* src, int sign) {
|
static void
|
||||||
|
decode_bc6_block(rgb32f *col, const UINT8 *src, int sign) {
|
||||||
UINT16 endpoints[12]; /* storage for r0, g0, b0, r1, ... */
|
UINT16 endpoints[12]; /* storage for r0, g0, b0, r1, ... */
|
||||||
int ueps[12];
|
int ueps[12];
|
||||||
int i, i0, ib2, di, dw, mask, numep, s;
|
int i, i0, ib2, di, dw, mask, numep, s;
|
||||||
|
@ -773,7 +767,8 @@ static void decode_bc6_block(rgb32f *col, const UINT8* src, int sign) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void put_block(Imaging im, ImagingCodecState state, const char *col, int sz, int C) {
|
static void
|
||||||
|
put_block(Imaging im, ImagingCodecState state, const char *col, int sz, int C) {
|
||||||
int width = state->xsize;
|
int width = state->xsize;
|
||||||
int height = state->ysize;
|
int height = state->ysize;
|
||||||
int xmax = width + state->xoff;
|
int xmax = width + state->xoff;
|
||||||
|
@ -813,7 +808,9 @@ static void put_block(Imaging im, ImagingCodecState state, const char *col, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_bcn(Imaging im, ImagingCodecState state, const UINT8* src, int bytes, int N, int C) {
|
static int
|
||||||
|
decode_bcn(
|
||||||
|
Imaging im, ImagingCodecState state, const UINT8 *src, int bytes, int N, int C) {
|
||||||
int ymax = state->ysize + state->yoff;
|
int ymax = state->ysize + state->yoff;
|
||||||
const UINT8 *ptr = src;
|
const UINT8 *ptr = src;
|
||||||
switch (N) {
|
switch (N) {
|
||||||
|
@ -844,9 +841,9 @@ static int decode_bcn(Imaging im, ImagingCodecState state, const UINT8* src, int
|
||||||
put_block(im, state, (const char *)col, sizeof(col[0]), C);
|
put_block(im, state, (const char *)col, sizeof(col[0]), C);
|
||||||
ptr += 16;
|
ptr += 16;
|
||||||
bytes -= 16;
|
bytes -= 16;
|
||||||
if (state->y >= ymax) {\
|
if (state->y >= ymax) {
|
||||||
return -1; \
|
return -1;
|
||||||
}\
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
DECODE_LOOP(7, 16, rgba);
|
DECODE_LOOP(7, 16, rgba);
|
||||||
|
@ -855,7 +852,8 @@ static int decode_bcn(Imaging im, ImagingCodecState state, const UINT8* src, int
|
||||||
return (int)(ptr - src);
|
return (int)(ptr - src);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImagingBcnDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes) {
|
int
|
||||||
|
ImagingBcnDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
int N = state->state & 0xf;
|
int N = state->state & 0xf;
|
||||||
int width = state->xsize;
|
int width = state->xsize;
|
||||||
int height = state->ysize;
|
int height = state->ysize;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* Bit.h */
|
/* Bit.h */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* CONFIGURATION */
|
/* CONFIGURATION */
|
||||||
|
|
||||||
/* Number of bits per pixel */
|
/* Number of bits per pixel */
|
||||||
|
|
|
@ -13,20 +13,16 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#include "Bit.h"
|
#include "Bit.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
BITSTATE *bitstate = state->context;
|
BITSTATE *bitstate = state->context;
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
|
|
||||||
if (state->state == 0) {
|
if (state->state == 0) {
|
||||||
|
|
||||||
/* Initialize context variables */
|
/* Initialize context variables */
|
||||||
|
|
||||||
/* this decoder only works for float32 image buffers */
|
/* this decoder only works for float32 image buffers */
|
||||||
|
@ -56,13 +52,11 @@ ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
}
|
}
|
||||||
|
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
while (bytes > 0) {
|
while (bytes > 0) {
|
||||||
|
|
||||||
UINT8 byte = *ptr;
|
UINT8 byte = *ptr;
|
||||||
|
|
||||||
ptr++;
|
ptr++;
|
||||||
|
@ -80,7 +74,6 @@ ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
bitstate->bitcount += 8;
|
bitstate->bitcount += 8;
|
||||||
|
|
||||||
while (bitstate->bitcount >= bitstate->bits) {
|
while (bitstate->bitcount >= bitstate->bits) {
|
||||||
|
|
||||||
/* get a pixel from the bit buffer */
|
/* get a pixel from the bit buffer */
|
||||||
unsigned long data;
|
unsigned long data;
|
||||||
FLOAT32 pixel;
|
FLOAT32 pixel;
|
||||||
|
@ -90,16 +83,15 @@ ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
data = bitstate->bitbuffer & bitstate->mask;
|
data = bitstate->bitbuffer & bitstate->mask;
|
||||||
if (bitstate->bitcount > 32) {
|
if (bitstate->bitcount > 32) {
|
||||||
/* bitbuffer overflow; restore it from last input byte */
|
/* bitbuffer overflow; restore it from last input byte */
|
||||||
bitstate->bitbuffer = byte >> (8 - (bitstate->bitcount -
|
bitstate->bitbuffer =
|
||||||
bitstate->bits));
|
byte >> (8 - (bitstate->bitcount - bitstate->bits));
|
||||||
} else {
|
} else {
|
||||||
bitstate->bitbuffer >>= bitstate->bits;
|
bitstate->bitbuffer >>= bitstate->bits;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* store MSB first */
|
/* store MSB first */
|
||||||
data = (bitstate->bitbuffer >> (bitstate->bitcount -
|
data = (bitstate->bitbuffer >> (bitstate->bitcount - bitstate->bits)) &
|
||||||
bitstate->bits))
|
bitstate->mask;
|
||||||
& bitstate->mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bitstate->bitcount -= bitstate->bits;
|
bitstate->bitcount -= bitstate->bits;
|
||||||
|
|
|
@ -15,27 +15,22 @@
|
||||||
* See the README file for details on usage and redistribution.
|
* See the README file for details on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
|
ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) {
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8
|
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette ||
|
||||||
|| imIn1->palette || strcmp(imIn1->mode, "1") == 0
|
strcmp(imIn1->mode, "1") == 0 || imIn2->palette ||
|
||||||
|| imIn2->palette || strcmp(imIn2->mode, "1") == 0) {
|
strcmp(imIn2->mode, "1") == 0) {
|
||||||
return ImagingError_ModeError();
|
return ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imIn1->type != imIn2->type ||
|
if (imIn1->type != imIn2->type || imIn1->bands != imIn2->bands ||
|
||||||
imIn1->bands != imIn2->bands ||
|
imIn1->xsize != imIn2->xsize || imIn1->ysize != imIn2->ysize) {
|
||||||
imIn1->xsize != imIn2->xsize ||
|
|
||||||
imIn1->ysize != imIn2->ysize) {
|
|
||||||
return ImagingError_Mismatch();
|
return ImagingError_Mismatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +53,7 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
|
||||||
UINT8 *in2 = (UINT8 *)imIn2->image[y];
|
UINT8 *in2 = (UINT8 *)imIn2->image[y];
|
||||||
UINT8 *out = (UINT8 *)imOut->image[y];
|
UINT8 *out = (UINT8 *)imOut->image[y];
|
||||||
for (x = 0; x < imIn1->linesize; x++) {
|
for (x = 0; x < imIn1->linesize; x++) {
|
||||||
out[x] = (UINT8)
|
out[x] = (UINT8)((int)in1[x] + alpha * ((int)in2[x] - (int)in1[x]));
|
||||||
((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,8 +63,7 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
|
||||||
UINT8 *in2 = (UINT8 *)imIn2->image[y];
|
UINT8 *in2 = (UINT8 *)imIn2->image[y];
|
||||||
UINT8 *out = (UINT8 *)imOut->image[y];
|
UINT8 *out = (UINT8 *)imOut->image[y];
|
||||||
for (x = 0; x < imIn1->linesize; x++) {
|
for (x = 0; x < imIn1->linesize; x++) {
|
||||||
float temp = (float)
|
float temp = (float)((int)in1[x] + alpha * ((int)in2[x] - (int)in1[x]));
|
||||||
((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x]));
|
|
||||||
if (temp <= 0.0) {
|
if (temp <= 0.0) {
|
||||||
out[x] = 0;
|
out[x] = 0;
|
||||||
} else if (temp >= 255.0) {
|
} else if (temp >= 255.0) {
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||||
|
|
||||||
|
|
||||||
typedef UINT8 pixel[4];
|
typedef UINT8 pixel[4];
|
||||||
|
|
||||||
void static inline
|
void static inline ImagingLineBoxBlur32(
|
||||||
ImagingLineBoxBlur32(pixel *lineOut, pixel *lineIn, int lastx, int radius, int edgeA,
|
pixel *lineOut,
|
||||||
int edgeB, UINT32 ww, UINT32 fw)
|
pixel *lineIn,
|
||||||
{
|
int lastx,
|
||||||
|
int radius,
|
||||||
|
int edgeA,
|
||||||
|
int edgeB,
|
||||||
|
UINT32 ww,
|
||||||
|
UINT32 fw) {
|
||||||
int x;
|
int x;
|
||||||
UINT32 acc[4];
|
UINT32 acc[4];
|
||||||
UINT32 bulk[4];
|
UINT32 bulk[4];
|
||||||
|
@ -53,8 +56,7 @@ ImagingLineBoxBlur32(pixel *lineOut, pixel *lineIn, int lastx, int radius, int e
|
||||||
acc[2] += lineIn[lastx][2] * (radius - edgeA + 1);
|
acc[2] += lineIn[lastx][2] * (radius - edgeA + 1);
|
||||||
acc[3] += lineIn[lastx][3] * (radius - edgeA + 1);
|
acc[3] += lineIn[lastx][3] * (radius - edgeA + 1);
|
||||||
|
|
||||||
if (edgeA <= edgeB)
|
if (edgeA <= edgeB) {
|
||||||
{
|
|
||||||
/* Subtract pixel from left ("0").
|
/* Subtract pixel from left ("0").
|
||||||
Add pixels from radius. */
|
Add pixels from radius. */
|
||||||
for (x = 0; x < edgeA; x++) {
|
for (x = 0; x < edgeA; x++) {
|
||||||
|
@ -76,9 +78,7 @@ ImagingLineBoxBlur32(pixel *lineOut, pixel *lineIn, int lastx, int radius, int e
|
||||||
ADD_FAR(bulk, acc, x - radius - 1, lastx);
|
ADD_FAR(bulk, acc, x - radius - 1, lastx);
|
||||||
SAVE(x, bulk);
|
SAVE(x, bulk);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
for (x = 0; x < edgeB; x++) {
|
for (x = 0; x < edgeB; x++) {
|
||||||
MOVE_ACC(acc, 0, x + radius);
|
MOVE_ACC(acc, 0, x + radius);
|
||||||
ADD_FAR(bulk, acc, 0, x + radius + 1);
|
ADD_FAR(bulk, acc, 0, x + radius + 1);
|
||||||
|
@ -101,23 +101,25 @@ ImagingLineBoxBlur32(pixel *lineOut, pixel *lineIn, int lastx, int radius, int e
|
||||||
#undef SAVE
|
#undef SAVE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void static inline ImagingLineBoxBlur8(
|
||||||
void static inline
|
UINT8 *lineOut,
|
||||||
ImagingLineBoxBlur8(UINT8 *lineOut, UINT8 *lineIn, int lastx, int radius, int edgeA,
|
UINT8 *lineIn,
|
||||||
int edgeB, UINT32 ww, UINT32 fw)
|
int lastx,
|
||||||
{
|
int radius,
|
||||||
|
int edgeA,
|
||||||
|
int edgeB,
|
||||||
|
UINT32 ww,
|
||||||
|
UINT32 fw) {
|
||||||
int x;
|
int x;
|
||||||
UINT32 acc;
|
UINT32 acc;
|
||||||
UINT32 bulk;
|
UINT32 bulk;
|
||||||
|
|
||||||
#define MOVE_ACC(acc, subtract, add) \
|
#define MOVE_ACC(acc, subtract, add) acc += lineIn[add] - lineIn[subtract];
|
||||||
acc += lineIn[add] - lineIn[subtract];
|
|
||||||
|
|
||||||
#define ADD_FAR(bulk, acc, left, right) \
|
#define ADD_FAR(bulk, acc, left, right) \
|
||||||
bulk = (acc * ww) + (lineIn[left] + lineIn[right]) * fw;
|
bulk = (acc * ww) + (lineIn[left] + lineIn[right]) * fw;
|
||||||
|
|
||||||
#define SAVE(x, bulk) \
|
#define SAVE(x, bulk) lineOut[x] = (UINT8)((bulk + (1 << 23)) >> 24)
|
||||||
lineOut[x] = (UINT8)((bulk + (1 << 23)) >> 24)
|
|
||||||
|
|
||||||
acc = lineIn[0] * (radius + 1);
|
acc = lineIn[0] * (radius + 1);
|
||||||
for (x = 0; x < edgeA - 1; x++) {
|
for (x = 0; x < edgeA - 1; x++) {
|
||||||
|
@ -125,8 +127,7 @@ ImagingLineBoxBlur8(UINT8 *lineOut, UINT8 *lineIn, int lastx, int radius, int ed
|
||||||
}
|
}
|
||||||
acc += lineIn[lastx] * (radius - edgeA + 1);
|
acc += lineIn[lastx] * (radius - edgeA + 1);
|
||||||
|
|
||||||
if (edgeA <= edgeB)
|
if (edgeA <= edgeB) {
|
||||||
{
|
|
||||||
for (x = 0; x < edgeA; x++) {
|
for (x = 0; x < edgeA; x++) {
|
||||||
MOVE_ACC(acc, 0, x + radius);
|
MOVE_ACC(acc, 0, x + radius);
|
||||||
ADD_FAR(bulk, acc, 0, x + radius + 1);
|
ADD_FAR(bulk, acc, 0, x + radius + 1);
|
||||||
|
@ -142,9 +143,7 @@ ImagingLineBoxBlur8(UINT8 *lineOut, UINT8 *lineIn, int lastx, int radius, int ed
|
||||||
ADD_FAR(bulk, acc, x - radius - 1, lastx);
|
ADD_FAR(bulk, acc, x - radius - 1, lastx);
|
||||||
SAVE(x, bulk);
|
SAVE(x, bulk);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
for (x = 0; x < edgeB; x++) {
|
for (x = 0; x < edgeB; x++) {
|
||||||
MOVE_ACC(acc, 0, x + radius);
|
MOVE_ACC(acc, 0, x + radius);
|
||||||
ADD_FAR(bulk, acc, 0, x + radius + 1);
|
ADD_FAR(bulk, acc, 0, x + radius + 1);
|
||||||
|
@ -167,11 +166,8 @@ ImagingLineBoxBlur8(UINT8 *lineOut, UINT8 *lineIn, int lastx, int radius, int ed
|
||||||
#undef SAVE
|
#undef SAVE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingHorizontalBoxBlur(Imaging imOut, Imaging imIn, float floatRadius)
|
ImagingHorizontalBoxBlur(Imaging imOut, Imaging imIn, float floatRadius) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
|
|
||||||
int y;
|
int y;
|
||||||
|
@ -192,32 +188,33 @@ ImagingHorizontalBoxBlur(Imaging imOut, Imaging imIn, float floatRadius)
|
||||||
|
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
if (imIn->image8)
|
if (imIn->image8) {
|
||||||
{
|
|
||||||
for (y = 0; y < imIn->ysize; y++) {
|
for (y = 0; y < imIn->ysize; y++) {
|
||||||
ImagingLineBoxBlur8(
|
ImagingLineBoxBlur8(
|
||||||
(imIn == imOut ? (UINT8 *)lineOut : imOut->image8[y]),
|
(imIn == imOut ? (UINT8 *)lineOut : imOut->image8[y]),
|
||||||
imIn->image8[y],
|
imIn->image8[y],
|
||||||
imIn->xsize - 1,
|
imIn->xsize - 1,
|
||||||
radius, edgeA, edgeB,
|
radius,
|
||||||
ww, fw
|
edgeA,
|
||||||
);
|
edgeB,
|
||||||
|
ww,
|
||||||
|
fw);
|
||||||
if (imIn == imOut) {
|
if (imIn == imOut) {
|
||||||
// Commit.
|
// Commit.
|
||||||
memcpy(imOut->image8[y], lineOut, imIn->xsize);
|
memcpy(imOut->image8[y], lineOut, imIn->xsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
for (y = 0; y < imIn->ysize; y++) {
|
for (y = 0; y < imIn->ysize; y++) {
|
||||||
ImagingLineBoxBlur32(
|
ImagingLineBoxBlur32(
|
||||||
imIn == imOut ? (pixel *)lineOut : (pixel *)imOut->image32[y],
|
imIn == imOut ? (pixel *)lineOut : (pixel *)imOut->image32[y],
|
||||||
(pixel *)imIn->image32[y],
|
(pixel *)imIn->image32[y],
|
||||||
imIn->xsize - 1,
|
imIn->xsize - 1,
|
||||||
radius, edgeA, edgeB,
|
radius,
|
||||||
ww, fw
|
edgeA,
|
||||||
);
|
edgeB,
|
||||||
|
ww,
|
||||||
|
fw);
|
||||||
if (imIn == imOut) {
|
if (imIn == imOut) {
|
||||||
// Commit.
|
// Commit.
|
||||||
memcpy(imOut->image32[y], lineOut, imIn->xsize * 4);
|
memcpy(imOut->image32[y], lineOut, imIn->xsize * 4);
|
||||||
|
@ -232,23 +229,17 @@ ImagingHorizontalBoxBlur(Imaging imOut, Imaging imIn, float floatRadius)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n)
|
ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
Imaging imTransposed;
|
Imaging imTransposed;
|
||||||
|
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
return ImagingError_ValueError(
|
return ImagingError_ValueError("number of passes must be greater than zero");
|
||||||
"number of passes must be greater than zero"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(imIn->mode, imOut->mode) ||
|
if (strcmp(imIn->mode, imOut->mode) || imIn->type != imOut->type ||
|
||||||
imIn->type != imOut->type ||
|
imIn->bands != imOut->bands || imIn->xsize != imOut->xsize ||
|
||||||
imIn->bands != imOut->bands ||
|
|
||||||
imIn->xsize != imOut->xsize ||
|
|
||||||
imIn->ysize != imOut->ysize) {
|
imIn->ysize != imOut->ysize) {
|
||||||
return ImagingError_Mismatch();
|
return ImagingError_Mismatch();
|
||||||
}
|
}
|
||||||
|
@ -257,14 +248,10 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n)
|
||||||
return ImagingError_ModeError();
|
return ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(strcmp(imIn->mode, "RGB") == 0 ||
|
if (!(strcmp(imIn->mode, "RGB") == 0 || strcmp(imIn->mode, "RGBA") == 0 ||
|
||||||
strcmp(imIn->mode, "RGBA") == 0 ||
|
strcmp(imIn->mode, "RGBa") == 0 || strcmp(imIn->mode, "RGBX") == 0 ||
|
||||||
strcmp(imIn->mode, "RGBa") == 0 ||
|
strcmp(imIn->mode, "CMYK") == 0 || strcmp(imIn->mode, "L") == 0 ||
|
||||||
strcmp(imIn->mode, "RGBX") == 0 ||
|
strcmp(imIn->mode, "LA") == 0 || strcmp(imIn->mode, "La") == 0)) {
|
||||||
strcmp(imIn->mode, "CMYK") == 0 ||
|
|
||||||
strcmp(imIn->mode, "L") == 0 ||
|
|
||||||
strcmp(imIn->mode, "LA") == 0 ||
|
|
||||||
strcmp(imIn->mode, "La") == 0)) {
|
|
||||||
return ImagingError_ModeError();
|
return ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,10 +282,8 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Imaging
|
||||||
Imaging ImagingGaussianBlur(Imaging imOut, Imaging imIn, float radius,
|
ImagingGaussianBlur(Imaging imOut, Imaging imIn, float radius, int passes) {
|
||||||
int passes)
|
|
||||||
{
|
|
||||||
float sigma2, L, l, a;
|
float sigma2, L, l, a;
|
||||||
|
|
||||||
sigma2 = radius * radius / passes;
|
sigma2 = radius * radius / passes;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* See the README file for details on usage and redistribution.
|
* See the README file for details on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#define CHOP(operation) \
|
#define CHOP(operation) \
|
||||||
|
@ -61,16 +60,14 @@
|
||||||
return imOut;
|
return imOut;
|
||||||
|
|
||||||
static Imaging
|
static Imaging
|
||||||
create(Imaging im1, Imaging im2, char* mode)
|
create(Imaging im1, Imaging im2, char *mode) {
|
||||||
{
|
|
||||||
int xsize, ysize;
|
int xsize, ysize;
|
||||||
|
|
||||||
if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 ||
|
if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 ||
|
||||||
(mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) {
|
(mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) {
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
if (im1->type != im2->type ||
|
if (im1->type != im2->type || im1->bands != im2->bands) {
|
||||||
im1->bands != im2->bands) {
|
|
||||||
return (Imaging)ImagingError_Mismatch();
|
return (Imaging)ImagingError_Mismatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,97 +78,85 @@ create(Imaging im1, Imaging im2, char* mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopLighter(Imaging imIn1, Imaging imIn2)
|
ImagingChopLighter(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP((in1[x] > in2[x]) ? in1[x] : in2[x]);
|
CHOP((in1[x] > in2[x]) ? in1[x] : in2[x]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopDarker(Imaging imIn1, Imaging imIn2)
|
ImagingChopDarker(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP((in1[x] < in2[x]) ? in1[x] : in2[x]);
|
CHOP((in1[x] < in2[x]) ? in1[x] : in2[x]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopDifference(Imaging imIn1, Imaging imIn2)
|
ImagingChopDifference(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP(abs((int)in1[x] - (int)in2[x]));
|
CHOP(abs((int)in1[x] - (int)in2[x]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopMultiply(Imaging imIn1, Imaging imIn2)
|
ImagingChopMultiply(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP((int)in1[x] * (int)in2[x] / 255);
|
CHOP((int)in1[x] * (int)in2[x] / 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopScreen(Imaging imIn1, Imaging imIn2)
|
ImagingChopScreen(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP(255 - ((int)(255 - in1[x]) * (int)(255 - in2[x])) / 255);
|
CHOP(255 - ((int)(255 - in1[x]) * (int)(255 - in2[x])) / 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset)
|
ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset) {
|
||||||
{
|
|
||||||
CHOP(((int)in1[x] + (int)in2[x]) / scale + offset);
|
CHOP(((int)in1[x] + (int)in2[x]) / scale + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset)
|
ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset) {
|
||||||
{
|
|
||||||
CHOP(((int)in1[x] - (int)in2[x]) / scale + offset);
|
CHOP(((int)in1[x] - (int)in2[x]) / scale + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopAnd(Imaging imIn1, Imaging imIn2)
|
ImagingChopAnd(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP2((in1[x] && in2[x]) ? 255 : 0, "1");
|
CHOP2((in1[x] && in2[x]) ? 255 : 0, "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopOr(Imaging imIn1, Imaging imIn2)
|
ImagingChopOr(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP2((in1[x] || in2[x]) ? 255 : 0, "1");
|
CHOP2((in1[x] || in2[x]) ? 255 : 0, "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopXor(Imaging imIn1, Imaging imIn2)
|
ImagingChopXor(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, "1");
|
CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopAddModulo(Imaging imIn1, Imaging imIn2)
|
ImagingChopAddModulo(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP2(in1[x] + in2[x], NULL);
|
CHOP2(in1[x] + in2[x], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2)
|
ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
|
||||||
CHOP2(in1[x] - in2[x], NULL);
|
CHOP2(in1[x] - in2[x], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopSoftLight(Imaging imIn1, Imaging imIn2)
|
ImagingChopSoftLight(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
CHOP2(
|
||||||
CHOP2( (((255-in1[x]) * (in1[x]*in2[x]) ) / 65536) +
|
(((255 - in1[x]) * (in1[x] * in2[x])) / 65536) +
|
||||||
(in1[x] * ( 255 - ( (255 - in1[x]) * (255 - in2[x] ) / 255) )) / 255
|
(in1[x] * (255 - ((255 - in1[x]) * (255 - in2[x]) / 255))) / 255,
|
||||||
, NULL );
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingChopHardLight(Imaging imIn1, Imaging imIn2)
|
ImagingChopHardLight(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
CHOP2(
|
||||||
CHOP2( (in2[x]<128) ? ( (in1[x]*in2[x])/127)
|
(in2[x] < 128) ? ((in1[x] * in2[x]) / 127)
|
||||||
: 255 - ( ((255-in2[x]) * (255-in1[x])) / 127)
|
: 255 - (((255 - in2[x]) * (255 - in1[x])) / 127),
|
||||||
, NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingOverlay(Imaging imIn1, Imaging imIn2)
|
ImagingOverlay(Imaging imIn1, Imaging imIn2) {
|
||||||
{
|
CHOP2(
|
||||||
CHOP2( (in1[x]<128) ? ( (in1[x]*in2[x])/127)
|
(in1[x] < 128) ? ((in1[x] * in2[x]) / 127)
|
||||||
: 255 - ( ((255-in1[x]) * (255-in2[x])) / 127)
|
: 255 - (((255 - in1[x]) * (255 - in2[x])) / 127),
|
||||||
, NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
/* 8 bits for result. Table can overflow [0, 1.0] range,
|
/* 8 bits for result. Table can overflow [0, 1.0] range,
|
||||||
so we need extra bits for overflow and negative values.
|
so we need extra bits for overflow and negative values.
|
||||||
NOTE: This value should be the same as in _imaging/_prepare_lut_table() */
|
NOTE: This value should be the same as in _imaging/_prepare_lut_table() */
|
||||||
|
@ -16,23 +15,20 @@
|
||||||
|
|
||||||
#define SHIFT_BITS (16 - 1)
|
#define SHIFT_BITS (16 - 1)
|
||||||
|
|
||||||
|
static inline UINT8
|
||||||
static inline UINT8 clip8(int in)
|
clip8(int in) {
|
||||||
{
|
|
||||||
return clip8_lookups[(in + PRECISION_ROUNDING) >> PRECISION_BITS];
|
return clip8_lookups[(in + PRECISION_ROUNDING) >> PRECISION_BITS];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
interpolate3(INT16 out[3], const INT16 a[3], const INT16 b[3], INT16 shift)
|
interpolate3(INT16 out[3], const INT16 a[3], const INT16 b[3], INT16 shift) {
|
||||||
{
|
|
||||||
out[0] = (a[0] * ((1 << SHIFT_BITS) - shift) + b[0] * shift) >> SHIFT_BITS;
|
out[0] = (a[0] * ((1 << SHIFT_BITS) - shift) + b[0] * shift) >> SHIFT_BITS;
|
||||||
out[1] = (a[1] * ((1 << SHIFT_BITS) - shift) + b[1] * shift) >> SHIFT_BITS;
|
out[1] = (a[1] * ((1 << SHIFT_BITS) - shift) + b[1] * shift) >> SHIFT_BITS;
|
||||||
out[2] = (a[2] * ((1 << SHIFT_BITS) - shift) + b[2] * shift) >> SHIFT_BITS;
|
out[2] = (a[2] * ((1 << SHIFT_BITS) - shift) + b[2] * shift) >> SHIFT_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
interpolate4(INT16 out[4], const INT16 a[4], const INT16 b[4], INT16 shift)
|
interpolate4(INT16 out[4], const INT16 a[4], const INT16 b[4], INT16 shift) {
|
||||||
{
|
|
||||||
out[0] = (a[0] * ((1 << SHIFT_BITS) - shift) + b[0] * shift) >> SHIFT_BITS;
|
out[0] = (a[0] * ((1 << SHIFT_BITS) - shift) + b[0] * shift) >> SHIFT_BITS;
|
||||||
out[1] = (a[1] * ((1 << SHIFT_BITS) - shift) + b[1] * shift) >> SHIFT_BITS;
|
out[1] = (a[1] * ((1 << SHIFT_BITS) - shift) + b[1] * shift) >> SHIFT_BITS;
|
||||||
out[2] = (a[2] * ((1 << SHIFT_BITS) - shift) + b[2] * shift) >> SHIFT_BITS;
|
out[2] = (a[2] * ((1 << SHIFT_BITS) - shift) + b[2] * shift) >> SHIFT_BITS;
|
||||||
|
@ -40,13 +36,10 @@ interpolate4(INT16 out[4], const INT16 a[4], const INT16 b[4], INT16 shift)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
table_index3D(int index1D, int index2D, int index3D,
|
table_index3D(int index1D, int index2D, int index3D, int size1D, int size1D_2D) {
|
||||||
int size1D, int size1D_2D)
|
|
||||||
{
|
|
||||||
return index1D + index2D * size1D + index3D * size1D_2D;
|
return index1D + index2D * size1D + index3D * size1D_2D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Transforms colors of imIn using provided 3D lookup table
|
Transforms colors of imIn using provided 3D lookup table
|
||||||
and puts the result in imOut. Returns imOut on success or 0 on error.
|
and puts the result in imOut. Returns imOut on success or 0 on error.
|
||||||
|
@ -63,10 +56,14 @@ table_index3D(int index1D, int index2D, int index3D,
|
||||||
and 255 << PRECISION_BITS (16320) is highest value.
|
and 255 << PRECISION_BITS (16320) is highest value.
|
||||||
*/
|
*/
|
||||||
Imaging
|
Imaging
|
||||||
ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels,
|
ImagingColorLUT3D_linear(
|
||||||
int size1D, int size2D, int size3D,
|
Imaging imOut,
|
||||||
INT16* table)
|
Imaging imIn,
|
||||||
{
|
int table_channels,
|
||||||
|
int size1D,
|
||||||
|
int size2D,
|
||||||
|
int size3D,
|
||||||
|
INT16 *table) {
|
||||||
/* This float to int conversion doesn't have rounding
|
/* This float to int conversion doesn't have rounding
|
||||||
error compensation (+0.5) for two reasons:
|
error compensation (+0.5) for two reasons:
|
||||||
1. As we don't hit the highest value,
|
1. As we don't hit the highest value,
|
||||||
|
@ -89,11 +86,8 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imIn->type != IMAGING_TYPE_UINT8 ||
|
if (imIn->type != IMAGING_TYPE_UINT8 || imOut->type != IMAGING_TYPE_UINT8 ||
|
||||||
imOut->type != IMAGING_TYPE_UINT8 ||
|
imIn->bands < 3 || imOut->bands < table_channels) {
|
||||||
imIn->bands < 3 ||
|
|
||||||
imOut->bands < table_channels
|
|
||||||
) {
|
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,50 +108,75 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels,
|
||||||
INT16 shift2D = (SCALE_MASK & index2D) >> (SCALE_BITS - SHIFT_BITS);
|
INT16 shift2D = (SCALE_MASK & index2D) >> (SCALE_BITS - SHIFT_BITS);
|
||||||
INT16 shift3D = (SCALE_MASK & index3D) >> (SCALE_BITS - SHIFT_BITS);
|
INT16 shift3D = (SCALE_MASK & index3D) >> (SCALE_BITS - SHIFT_BITS);
|
||||||
int idx = table_channels * table_index3D(
|
int idx = table_channels * table_index3D(
|
||||||
index1D >> SCALE_BITS, index2D >> SCALE_BITS,
|
index1D >> SCALE_BITS,
|
||||||
index3D >> SCALE_BITS, size1D, size1D_2D);
|
index2D >> SCALE_BITS,
|
||||||
|
index3D >> SCALE_BITS,
|
||||||
|
size1D,
|
||||||
|
size1D_2D);
|
||||||
INT16 result[4], left[4], right[4];
|
INT16 result[4], left[4], right[4];
|
||||||
INT16 leftleft[4], leftright[4], rightleft[4], rightright[4];
|
INT16 leftleft[4], leftright[4], rightleft[4], rightright[4];
|
||||||
|
|
||||||
if (table_channels == 3) {
|
if (table_channels == 3) {
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
interpolate3(leftleft, &table[idx + 0], &table[idx + 3], shift1D);
|
interpolate3(leftleft, &table[idx + 0], &table[idx + 3], shift1D);
|
||||||
interpolate3(leftright, &table[idx + size1D*3],
|
interpolate3(
|
||||||
&table[idx + size1D*3 + 3], shift1D);
|
leftright,
|
||||||
|
&table[idx + size1D * 3],
|
||||||
|
&table[idx + size1D * 3 + 3],
|
||||||
|
shift1D);
|
||||||
interpolate3(left, leftleft, leftright, shift2D);
|
interpolate3(left, leftleft, leftright, shift2D);
|
||||||
|
|
||||||
interpolate3(rightleft, &table[idx + size1D_2D*3],
|
interpolate3(
|
||||||
&table[idx + size1D_2D*3 + 3], shift1D);
|
rightleft,
|
||||||
interpolate3(rightright, &table[idx + size1D_2D*3 + size1D*3],
|
&table[idx + size1D_2D * 3],
|
||||||
&table[idx + size1D_2D*3 + size1D*3 + 3], shift1D);
|
&table[idx + size1D_2D * 3 + 3],
|
||||||
|
shift1D);
|
||||||
|
interpolate3(
|
||||||
|
rightright,
|
||||||
|
&table[idx + size1D_2D * 3 + size1D * 3],
|
||||||
|
&table[idx + size1D_2D * 3 + size1D * 3 + 3],
|
||||||
|
shift1D);
|
||||||
interpolate3(right, rightleft, rightright, shift2D);
|
interpolate3(right, rightleft, rightright, shift2D);
|
||||||
|
|
||||||
interpolate3(result, left, right, shift3D);
|
interpolate3(result, left, right, shift3D);
|
||||||
|
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
clip8(result[0]), clip8(result[1]),
|
clip8(result[0]),
|
||||||
clip8(result[2]), rowIn[x*4 + 3]);
|
clip8(result[1]),
|
||||||
|
clip8(result[2]),
|
||||||
|
rowIn[x * 4 + 3]);
|
||||||
memcpy(rowOut + x * sizeof(v), &v, sizeof(v));
|
memcpy(rowOut + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table_channels == 4) {
|
if (table_channels == 4) {
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
interpolate4(leftleft, &table[idx + 0], &table[idx + 4], shift1D);
|
interpolate4(leftleft, &table[idx + 0], &table[idx + 4], shift1D);
|
||||||
interpolate4(leftright, &table[idx + size1D*4],
|
interpolate4(
|
||||||
&table[idx + size1D*4 + 4], shift1D);
|
leftright,
|
||||||
|
&table[idx + size1D * 4],
|
||||||
|
&table[idx + size1D * 4 + 4],
|
||||||
|
shift1D);
|
||||||
interpolate4(left, leftleft, leftright, shift2D);
|
interpolate4(left, leftleft, leftright, shift2D);
|
||||||
|
|
||||||
interpolate4(rightleft, &table[idx + size1D_2D*4],
|
interpolate4(
|
||||||
&table[idx + size1D_2D*4 + 4], shift1D);
|
rightleft,
|
||||||
interpolate4(rightright, &table[idx + size1D_2D*4 + size1D*4],
|
&table[idx + size1D_2D * 4],
|
||||||
&table[idx + size1D_2D*4 + size1D*4 + 4], shift1D);
|
&table[idx + size1D_2D * 4 + 4],
|
||||||
|
shift1D);
|
||||||
|
interpolate4(
|
||||||
|
rightright,
|
||||||
|
&table[idx + size1D_2D * 4 + size1D * 4],
|
||||||
|
&table[idx + size1D_2D * 4 + size1D * 4 + 4],
|
||||||
|
shift1D);
|
||||||
interpolate4(right, rightleft, rightright, shift2D);
|
interpolate4(right, rightleft, rightright, shift2D);
|
||||||
|
|
||||||
interpolate4(result, left, right, shift3D);
|
interpolate4(result, left, right, shift3D);
|
||||||
|
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
clip8(result[0]), clip8(result[1]),
|
clip8(result[0]),
|
||||||
clip8(result[2]), clip8(result[3]));
|
clip8(result[1]),
|
||||||
|
clip8(result[2]),
|
||||||
|
clip8(result[3]));
|
||||||
memcpy(rowOut + x * sizeof(v), &v, sizeof(v));
|
memcpy(rowOut + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,322 +28,300 @@
|
||||||
|
|
||||||
#define SCALE 6 /* bits */
|
#define SCALE 6 /* bits */
|
||||||
|
|
||||||
static INT16 Y_R[] = { 0, 19, 38, 57, 77, 96, 115, 134, 153, 172, 191,
|
static INT16 Y_R[] = {
|
||||||
210, 230, 249, 268, 287, 306, 325, 344, 364, 383, 402, 421, 440, 459,
|
0, 19, 38, 57, 77, 96, 115, 134, 153, 172, 191, 210, 230, 249,
|
||||||
478, 498, 517, 536, 555, 574, 593, 612, 631, 651, 670, 689, 708, 727,
|
268, 287, 306, 325, 344, 364, 383, 402, 421, 440, 459, 478, 498, 517,
|
||||||
746, 765, 785, 804, 823, 842, 861, 880, 899, 919, 938, 957, 976, 995,
|
536, 555, 574, 593, 612, 631, 651, 670, 689, 708, 727, 746, 765, 785,
|
||||||
1014, 1033, 1052, 1072, 1091, 1110, 1129, 1148, 1167, 1186, 1206,
|
804, 823, 842, 861, 880, 899, 919, 938, 957, 976, 995, 1014, 1033, 1052,
|
||||||
1225, 1244, 1263, 1282, 1301, 1320, 1340, 1359, 1378, 1397, 1416,
|
1072, 1091, 1110, 1129, 1148, 1167, 1186, 1206, 1225, 1244, 1263, 1282, 1301, 1320,
|
||||||
1435, 1454, 1473, 1493, 1512, 1531, 1550, 1569, 1588, 1607, 1627,
|
1340, 1359, 1378, 1397, 1416, 1435, 1454, 1473, 1493, 1512, 1531, 1550, 1569, 1588,
|
||||||
1646, 1665, 1684, 1703, 1722, 1741, 1761, 1780, 1799, 1818, 1837,
|
1607, 1627, 1646, 1665, 1684, 1703, 1722, 1741, 1761, 1780, 1799, 1818, 1837, 1856,
|
||||||
1856, 1875, 1894, 1914, 1933, 1952, 1971, 1990, 2009, 2028, 2048,
|
1875, 1894, 1914, 1933, 1952, 1971, 1990, 2009, 2028, 2048, 2067, 2086, 2105, 2124,
|
||||||
2067, 2086, 2105, 2124, 2143, 2162, 2182, 2201, 2220, 2239, 2258,
|
2143, 2162, 2182, 2201, 2220, 2239, 2258, 2277, 2296, 2315, 2335, 2354, 2373, 2392,
|
||||||
2277, 2296, 2315, 2335, 2354, 2373, 2392, 2411, 2430, 2449, 2469,
|
2411, 2430, 2449, 2469, 2488, 2507, 2526, 2545, 2564, 2583, 2602, 2622, 2641, 2660,
|
||||||
2488, 2507, 2526, 2545, 2564, 2583, 2602, 2622, 2641, 2660, 2679,
|
2679, 2698, 2717, 2736, 2756, 2775, 2794, 2813, 2832, 2851, 2870, 2890, 2909, 2928,
|
||||||
2698, 2717, 2736, 2756, 2775, 2794, 2813, 2832, 2851, 2870, 2890,
|
2947, 2966, 2985, 3004, 3023, 3043, 3062, 3081, 3100, 3119, 3138, 3157, 3177, 3196,
|
||||||
2909, 2928, 2947, 2966, 2985, 3004, 3023, 3043, 3062, 3081, 3100,
|
3215, 3234, 3253, 3272, 3291, 3311, 3330, 3349, 3368, 3387, 3406, 3425, 3444, 3464,
|
||||||
3119, 3138, 3157, 3177, 3196, 3215, 3234, 3253, 3272, 3291, 3311,
|
3483, 3502, 3521, 3540, 3559, 3578, 3598, 3617, 3636, 3655, 3674, 3693, 3712, 3732,
|
||||||
3330, 3349, 3368, 3387, 3406, 3425, 3444, 3464, 3483, 3502, 3521,
|
3751, 3770, 3789, 3808, 3827, 3846, 3865, 3885, 3904, 3923, 3942, 3961, 3980, 3999,
|
||||||
3540, 3559, 3578, 3598, 3617, 3636, 3655, 3674, 3693, 3712, 3732,
|
4019, 4038, 4057, 4076, 4095, 4114, 4133, 4153, 4172, 4191, 4210, 4229, 4248, 4267,
|
||||||
3751, 3770, 3789, 3808, 3827, 3846, 3865, 3885, 3904, 3923, 3942,
|
4286, 4306, 4325, 4344, 4363, 4382, 4401, 4420, 4440, 4459, 4478, 4497, 4516, 4535,
|
||||||
3961, 3980, 3999, 4019, 4038, 4057, 4076, 4095, 4114, 4133, 4153,
|
4554, 4574, 4593, 4612, 4631, 4650, 4669, 4688, 4707, 4727, 4746, 4765, 4784, 4803,
|
||||||
4172, 4191, 4210, 4229, 4248, 4267, 4286, 4306, 4325, 4344, 4363,
|
4822, 4841, 4861, 4880};
|
||||||
4382, 4401, 4420, 4440, 4459, 4478, 4497, 4516, 4535, 4554, 4574,
|
|
||||||
4593, 4612, 4631, 4650, 4669, 4688, 4707, 4727, 4746, 4765, 4784,
|
|
||||||
4803, 4822, 4841, 4861, 4880 };
|
|
||||||
|
|
||||||
static INT16 Y_G[] = { 0, 38, 75, 113, 150, 188, 225, 263, 301, 338,
|
static INT16 Y_G[] = {
|
||||||
376, 413, 451, 488, 526, 564, 601, 639, 676, 714, 751, 789, 826, 864,
|
0, 38, 75, 113, 150, 188, 225, 263, 301, 338, 376, 413, 451, 488,
|
||||||
902, 939, 977, 1014, 1052, 1089, 1127, 1165, 1202, 1240, 1277, 1315,
|
526, 564, 601, 639, 676, 714, 751, 789, 826, 864, 902, 939, 977, 1014,
|
||||||
1352, 1390, 1428, 1465, 1503, 1540, 1578, 1615, 1653, 1691, 1728,
|
1052, 1089, 1127, 1165, 1202, 1240, 1277, 1315, 1352, 1390, 1428, 1465, 1503, 1540,
|
||||||
1766, 1803, 1841, 1878, 1916, 1954, 1991, 2029, 2066, 2104, 2141,
|
1578, 1615, 1653, 1691, 1728, 1766, 1803, 1841, 1878, 1916, 1954, 1991, 2029, 2066,
|
||||||
2179, 2217, 2254, 2292, 2329, 2367, 2404, 2442, 2479, 2517, 2555,
|
2104, 2141, 2179, 2217, 2254, 2292, 2329, 2367, 2404, 2442, 2479, 2517, 2555, 2592,
|
||||||
2592, 2630, 2667, 2705, 2742, 2780, 2818, 2855, 2893, 2930, 2968,
|
2630, 2667, 2705, 2742, 2780, 2818, 2855, 2893, 2930, 2968, 3005, 3043, 3081, 3118,
|
||||||
3005, 3043, 3081, 3118, 3156, 3193, 3231, 3268, 3306, 3344, 3381,
|
3156, 3193, 3231, 3268, 3306, 3344, 3381, 3419, 3456, 3494, 3531, 3569, 3607, 3644,
|
||||||
3419, 3456, 3494, 3531, 3569, 3607, 3644, 3682, 3719, 3757, 3794,
|
3682, 3719, 3757, 3794, 3832, 3870, 3907, 3945, 3982, 4020, 4057, 4095, 4132, 4170,
|
||||||
3832, 3870, 3907, 3945, 3982, 4020, 4057, 4095, 4132, 4170, 4208,
|
4208, 4245, 4283, 4320, 4358, 4395, 4433, 4471, 4508, 4546, 4583, 4621, 4658, 4696,
|
||||||
4245, 4283, 4320, 4358, 4395, 4433, 4471, 4508, 4546, 4583, 4621,
|
4734, 4771, 4809, 4846, 4884, 4921, 4959, 4997, 5034, 5072, 5109, 5147, 5184, 5222,
|
||||||
4658, 4696, 4734, 4771, 4809, 4846, 4884, 4921, 4959, 4997, 5034,
|
5260, 5297, 5335, 5372, 5410, 5447, 5485, 5522, 5560, 5598, 5635, 5673, 5710, 5748,
|
||||||
5072, 5109, 5147, 5184, 5222, 5260, 5297, 5335, 5372, 5410, 5447,
|
5785, 5823, 5861, 5898, 5936, 5973, 6011, 6048, 6086, 6124, 6161, 6199, 6236, 6274,
|
||||||
5485, 5522, 5560, 5598, 5635, 5673, 5710, 5748, 5785, 5823, 5861,
|
6311, 6349, 6387, 6424, 6462, 6499, 6537, 6574, 6612, 6650, 6687, 6725, 6762, 6800,
|
||||||
5898, 5936, 5973, 6011, 6048, 6086, 6124, 6161, 6199, 6236, 6274,
|
6837, 6875, 6913, 6950, 6988, 7025, 7063, 7100, 7138, 7175, 7213, 7251, 7288, 7326,
|
||||||
6311, 6349, 6387, 6424, 6462, 6499, 6537, 6574, 6612, 6650, 6687,
|
7363, 7401, 7438, 7476, 7514, 7551, 7589, 7626, 7664, 7701, 7739, 7777, 7814, 7852,
|
||||||
6725, 6762, 6800, 6837, 6875, 6913, 6950, 6988, 7025, 7063, 7100,
|
7889, 7927, 7964, 8002, 8040, 8077, 8115, 8152, 8190, 8227, 8265, 8303, 8340, 8378,
|
||||||
7138, 7175, 7213, 7251, 7288, 7326, 7363, 7401, 7438, 7476, 7514,
|
8415, 8453, 8490, 8528, 8566, 8603, 8641, 8678, 8716, 8753, 8791, 8828, 8866, 8904,
|
||||||
7551, 7589, 7626, 7664, 7701, 7739, 7777, 7814, 7852, 7889, 7927,
|
8941, 8979, 9016, 9054, 9091, 9129, 9167, 9204, 9242, 9279, 9317, 9354, 9392, 9430,
|
||||||
7964, 8002, 8040, 8077, 8115, 8152, 8190, 8227, 8265, 8303, 8340,
|
9467, 9505, 9542, 9580};
|
||||||
8378, 8415, 8453, 8490, 8528, 8566, 8603, 8641, 8678, 8716, 8753,
|
|
||||||
8791, 8828, 8866, 8904, 8941, 8979, 9016, 9054, 9091, 9129, 9167,
|
|
||||||
9204, 9242, 9279, 9317, 9354, 9392, 9430, 9467, 9505, 9542, 9580 };
|
|
||||||
|
|
||||||
static INT16 Y_B[] = { 0, 7, 15, 22, 29, 36, 44, 51, 58, 66, 73, 80,
|
static INT16 Y_B[] = {
|
||||||
88, 95, 102, 109, 117, 124, 131, 139, 146, 153, 161, 168, 175, 182,
|
0, 7, 15, 22, 29, 36, 44, 51, 58, 66, 73, 80, 88, 95,
|
||||||
190, 197, 204, 212, 219, 226, 233, 241, 248, 255, 263, 270, 277, 285,
|
102, 109, 117, 124, 131, 139, 146, 153, 161, 168, 175, 182, 190, 197,
|
||||||
292, 299, 306, 314, 321, 328, 336, 343, 350, 358, 365, 372, 379, 387,
|
204, 212, 219, 226, 233, 241, 248, 255, 263, 270, 277, 285, 292, 299,
|
||||||
394, 401, 409, 416, 423, 430, 438, 445, 452, 460, 467, 474, 482, 489,
|
306, 314, 321, 328, 336, 343, 350, 358, 365, 372, 379, 387, 394, 401,
|
||||||
496, 503, 511, 518, 525, 533, 540, 547, 554, 562, 569, 576, 584, 591,
|
409, 416, 423, 430, 438, 445, 452, 460, 467, 474, 482, 489, 496, 503,
|
||||||
598, 606, 613, 620, 627, 635, 642, 649, 657, 664, 671, 679, 686, 693,
|
511, 518, 525, 533, 540, 547, 554, 562, 569, 576, 584, 591, 598, 606,
|
||||||
700, 708, 715, 722, 730, 737, 744, 751, 759, 766, 773, 781, 788, 795,
|
613, 620, 627, 635, 642, 649, 657, 664, 671, 679, 686, 693, 700, 708,
|
||||||
803, 810, 817, 824, 832, 839, 846, 854, 861, 868, 876, 883, 890, 897,
|
715, 722, 730, 737, 744, 751, 759, 766, 773, 781, 788, 795, 803, 810,
|
||||||
905, 912, 919, 927, 934, 941, 948, 956, 963, 970, 978, 985, 992, 1000,
|
817, 824, 832, 839, 846, 854, 861, 868, 876, 883, 890, 897, 905, 912,
|
||||||
1007, 1014, 1021, 1029, 1036, 1043, 1051, 1058, 1065, 1073, 1080,
|
919, 927, 934, 941, 948, 956, 963, 970, 978, 985, 992, 1000, 1007, 1014,
|
||||||
1087, 1094, 1102, 1109, 1116, 1124, 1131, 1138, 1145, 1153, 1160,
|
1021, 1029, 1036, 1043, 1051, 1058, 1065, 1073, 1080, 1087, 1094, 1102, 1109, 1116,
|
||||||
1167, 1175, 1182, 1189, 1197, 1204, 1211, 1218, 1226, 1233, 1240,
|
1124, 1131, 1138, 1145, 1153, 1160, 1167, 1175, 1182, 1189, 1197, 1204, 1211, 1218,
|
||||||
1248, 1255, 1262, 1270, 1277, 1284, 1291, 1299, 1306, 1313, 1321,
|
1226, 1233, 1240, 1248, 1255, 1262, 1270, 1277, 1284, 1291, 1299, 1306, 1313, 1321,
|
||||||
1328, 1335, 1342, 1350, 1357, 1364, 1372, 1379, 1386, 1394, 1401,
|
1328, 1335, 1342, 1350, 1357, 1364, 1372, 1379, 1386, 1394, 1401, 1408, 1415, 1423,
|
||||||
1408, 1415, 1423, 1430, 1437, 1445, 1452, 1459, 1466, 1474, 1481,
|
1430, 1437, 1445, 1452, 1459, 1466, 1474, 1481, 1488, 1496, 1503, 1510, 1518, 1525,
|
||||||
1488, 1496, 1503, 1510, 1518, 1525, 1532, 1539, 1547, 1554, 1561,
|
1532, 1539, 1547, 1554, 1561, 1569, 1576, 1583, 1591, 1598, 1605, 1612, 1620, 1627,
|
||||||
1569, 1576, 1583, 1591, 1598, 1605, 1612, 1620, 1627, 1634, 1642,
|
1634, 1642, 1649, 1656, 1663, 1671, 1678, 1685, 1693, 1700, 1707, 1715, 1722, 1729,
|
||||||
1649, 1656, 1663, 1671, 1678, 1685, 1693, 1700, 1707, 1715, 1722,
|
1736, 1744, 1751, 1758, 1766, 1773, 1780, 1788, 1795, 1802, 1809, 1817, 1824, 1831,
|
||||||
1729, 1736, 1744, 1751, 1758, 1766, 1773, 1780, 1788, 1795, 1802,
|
1839, 1846, 1853, 1860};
|
||||||
1809, 1817, 1824, 1831, 1839, 1846, 1853, 1860 };
|
|
||||||
|
|
||||||
static INT16 Cb_R[] = { 0, -10, -21, -31, -42, -53, -64, -75, -85,
|
static INT16 Cb_R[] = {
|
||||||
-96, -107, -118, -129, -139, -150, -161, -172, -183, -193, -204, -215,
|
0, -10, -21, -31, -42, -53, -64, -75, -85, -96, -107, -118,
|
||||||
-226, -237, -247, -258, -269, -280, -291, -301, -312, -323, -334,
|
-129, -139, -150, -161, -172, -183, -193, -204, -215, -226, -237, -247,
|
||||||
-345, -355, -366, -377, -388, -399, -409, -420, -431, -442, -453,
|
-258, -269, -280, -291, -301, -312, -323, -334, -345, -355, -366, -377,
|
||||||
-463, -474, -485, -496, -507, -517, -528, -539, -550, -561, -571,
|
-388, -399, -409, -420, -431, -442, -453, -463, -474, -485, -496, -507,
|
||||||
-582, -593, -604, -615, -625, -636, -647, -658, -669, -679, -690,
|
-517, -528, -539, -550, -561, -571, -582, -593, -604, -615, -625, -636,
|
||||||
-701, -712, -723, -733, -744, -755, -766, -777, -787, -798, -809,
|
-647, -658, -669, -679, -690, -701, -712, -723, -733, -744, -755, -766,
|
||||||
-820, -831, -841, -852, -863, -874, -885, -895, -906, -917, -928,
|
-777, -787, -798, -809, -820, -831, -841, -852, -863, -874, -885, -895,
|
||||||
-939, -949, -960, -971, -982, -993, -1003, -1014, -1025, -1036, -1047,
|
-906, -917, -928, -939, -949, -960, -971, -982, -993, -1003, -1014, -1025,
|
||||||
-1057, -1068, -1079, -1090, -1101, -1111, -1122, -1133, -1144, -1155,
|
-1036, -1047, -1057, -1068, -1079, -1090, -1101, -1111, -1122, -1133, -1144, -1155,
|
||||||
-1165, -1176, -1187, -1198, -1209, -1219, -1230, -1241, -1252, -1263,
|
-1165, -1176, -1187, -1198, -1209, -1219, -1230, -1241, -1252, -1263, -1273, -1284,
|
||||||
-1273, -1284, -1295, -1306, -1317, -1327, -1338, -1349, -1360, -1371,
|
-1295, -1306, -1317, -1327, -1338, -1349, -1360, -1371, -1381, -1392, -1403, -1414,
|
||||||
-1381, -1392, -1403, -1414, -1425, -1435, -1446, -1457, -1468, -1479,
|
-1425, -1435, -1446, -1457, -1468, -1479, -1489, -1500, -1511, -1522, -1533, -1543,
|
||||||
-1489, -1500, -1511, -1522, -1533, -1543, -1554, -1565, -1576, -1587,
|
-1554, -1565, -1576, -1587, -1597, -1608, -1619, -1630, -1641, -1651, -1662, -1673,
|
||||||
-1597, -1608, -1619, -1630, -1641, -1651, -1662, -1673, -1684, -1694,
|
-1684, -1694, -1705, -1716, -1727, -1738, -1748, -1759, -1770, -1781, -1792, -1802,
|
||||||
-1705, -1716, -1727, -1738, -1748, -1759, -1770, -1781, -1792, -1802,
|
-1813, -1824, -1835, -1846, -1856, -1867, -1878, -1889, -1900, -1910, -1921, -1932,
|
||||||
-1813, -1824, -1835, -1846, -1856, -1867, -1878, -1889, -1900, -1910,
|
-1943, -1954, -1964, -1975, -1986, -1997, -2008, -2018, -2029, -2040, -2051, -2062,
|
||||||
-1921, -1932, -1943, -1954, -1964, -1975, -1986, -1997, -2008, -2018,
|
-2072, -2083, -2094, -2105, -2116, -2126, -2137, -2148, -2159, -2170, -2180, -2191,
|
||||||
-2029, -2040, -2051, -2062, -2072, -2083, -2094, -2105, -2116, -2126,
|
-2202, -2213, -2224, -2234, -2245, -2256, -2267, -2278, -2288, -2299, -2310, -2321,
|
||||||
-2137, -2148, -2159, -2170, -2180, -2191, -2202, -2213, -2224, -2234,
|
-2332, -2342, -2353, -2364, -2375, -2386, -2396, -2407, -2418, -2429, -2440, -2450,
|
||||||
-2245, -2256, -2267, -2278, -2288, -2299, -2310, -2321, -2332, -2342,
|
-2461, -2472, -2483, -2494, -2504, -2515, -2526, -2537, -2548, -2558, -2569, -2580,
|
||||||
-2353, -2364, -2375, -2386, -2396, -2407, -2418, -2429, -2440, -2450,
|
-2591, -2602, -2612, -2623, -2634, -2645, -2656, -2666, -2677, -2688, -2699, -2710,
|
||||||
-2461, -2472, -2483, -2494, -2504, -2515, -2526, -2537, -2548, -2558,
|
-2720, -2731, -2742, -2753};
|
||||||
-2569, -2580, -2591, -2602, -2612, -2623, -2634, -2645, -2656, -2666,
|
|
||||||
-2677, -2688, -2699, -2710, -2720, -2731, -2742, -2753 };
|
|
||||||
|
|
||||||
static INT16 Cb_G[] = { 0, -20, -41, -63, -84, -105, -126, -147, -169,
|
static INT16 Cb_G[] = {
|
||||||
-190, -211, -232, -253, -275, -296, -317, -338, -359, -381, -402,
|
0, -20, -41, -63, -84, -105, -126, -147, -169, -190, -211, -232,
|
||||||
-423, -444, -465, -487, -508, -529, -550, -571, -593, -614, -635,
|
-253, -275, -296, -317, -338, -359, -381, -402, -423, -444, -465, -487,
|
||||||
-656, -677, -699, -720, -741, -762, -783, -805, -826, -847, -868,
|
-508, -529, -550, -571, -593, -614, -635, -656, -677, -699, -720, -741,
|
||||||
-889, -911, -932, -953, -974, -995, -1017, -1038, -1059, -1080, -1101,
|
-762, -783, -805, -826, -847, -868, -889, -911, -932, -953, -974, -995,
|
||||||
-1123, -1144, -1165, -1186, -1207, -1229, -1250, -1271, -1292, -1313,
|
-1017, -1038, -1059, -1080, -1101, -1123, -1144, -1165, -1186, -1207, -1229, -1250,
|
||||||
-1335, -1356, -1377, -1398, -1419, -1441, -1462, -1483, -1504, -1525,
|
-1271, -1292, -1313, -1335, -1356, -1377, -1398, -1419, -1441, -1462, -1483, -1504,
|
||||||
-1547, -1568, -1589, -1610, -1631, -1653, -1674, -1695, -1716, -1737,
|
-1525, -1547, -1568, -1589, -1610, -1631, -1653, -1674, -1695, -1716, -1737, -1759,
|
||||||
-1759, -1780, -1801, -1822, -1843, -1865, -1886, -1907, -1928, -1949,
|
-1780, -1801, -1822, -1843, -1865, -1886, -1907, -1928, -1949, -1971, -1992, -2013,
|
||||||
-1971, -1992, -2013, -2034, -2055, -2077, -2098, -2119, -2140, -2161,
|
-2034, -2055, -2077, -2098, -2119, -2140, -2161, -2183, -2204, -2225, -2246, -2267,
|
||||||
-2183, -2204, -2225, -2246, -2267, -2289, -2310, -2331, -2352, -2373,
|
-2289, -2310, -2331, -2352, -2373, -2395, -2416, -2437, -2458, -2479, -2501, -2522,
|
||||||
-2395, -2416, -2437, -2458, -2479, -2501, -2522, -2543, -2564, -2585,
|
-2543, -2564, -2585, -2607, -2628, -2649, -2670, -2691, -2713, -2734, -2755, -2776,
|
||||||
-2607, -2628, -2649, -2670, -2691, -2713, -2734, -2755, -2776, -2797,
|
-2797, -2819, -2840, -2861, -2882, -2903, -2925, -2946, -2967, -2988, -3009, -3031,
|
||||||
-2819, -2840, -2861, -2882, -2903, -2925, -2946, -2967, -2988, -3009,
|
-3052, -3073, -3094, -3115, -3137, -3158, -3179, -3200, -3221, -3243, -3264, -3285,
|
||||||
-3031, -3052, -3073, -3094, -3115, -3137, -3158, -3179, -3200, -3221,
|
-3306, -3328, -3349, -3370, -3391, -3412, -3434, -3455, -3476, -3497, -3518, -3540,
|
||||||
-3243, -3264, -3285, -3306, -3328, -3349, -3370, -3391, -3412, -3434,
|
-3561, -3582, -3603, -3624, -3646, -3667, -3688, -3709, -3730, -3752, -3773, -3794,
|
||||||
-3455, -3476, -3497, -3518, -3540, -3561, -3582, -3603, -3624, -3646,
|
-3815, -3836, -3858, -3879, -3900, -3921, -3942, -3964, -3985, -4006, -4027, -4048,
|
||||||
-3667, -3688, -3709, -3730, -3752, -3773, -3794, -3815, -3836, -3858,
|
-4070, -4091, -4112, -4133, -4154, -4176, -4197, -4218, -4239, -4260, -4282, -4303,
|
||||||
-3879, -3900, -3921, -3942, -3964, -3985, -4006, -4027, -4048, -4070,
|
-4324, -4345, -4366, -4388, -4409, -4430, -4451, -4472, -4494, -4515, -4536, -4557,
|
||||||
-4091, -4112, -4133, -4154, -4176, -4197, -4218, -4239, -4260, -4282,
|
-4578, -4600, -4621, -4642, -4663, -4684, -4706, -4727, -4748, -4769, -4790, -4812,
|
||||||
-4303, -4324, -4345, -4366, -4388, -4409, -4430, -4451, -4472, -4494,
|
-4833, -4854, -4875, -4896, -4918, -4939, -4960, -4981, -5002, -5024, -5045, -5066,
|
||||||
-4515, -4536, -4557, -4578, -4600, -4621, -4642, -4663, -4684, -4706,
|
-5087, -5108, -5130, -5151, -5172, -5193, -5214, -5236, -5257, -5278, -5299, -5320,
|
||||||
-4727, -4748, -4769, -4790, -4812, -4833, -4854, -4875, -4896, -4918,
|
-5342, -5363, -5384, -5405};
|
||||||
-4939, -4960, -4981, -5002, -5024, -5045, -5066, -5087, -5108, -5130,
|
|
||||||
-5151, -5172, -5193, -5214, -5236, -5257, -5278, -5299, -5320, -5342,
|
|
||||||
-5363, -5384, -5405 };
|
|
||||||
|
|
||||||
static INT16 Cb_B[] = { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288,
|
static INT16 Cb_B[] = {
|
||||||
320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736,
|
0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416,
|
||||||
768, 800, 832, 864, 896, 928, 960, 992, 1024, 1056, 1088, 1120, 1152,
|
448, 480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864,
|
||||||
1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472, 1504,
|
896, 928, 960, 992, 1024, 1056, 1088, 1120, 1152, 1184, 1216, 1248, 1280, 1312,
|
||||||
1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856,
|
1344, 1376, 1408, 1440, 1472, 1504, 1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760,
|
||||||
1888, 1920, 1952, 1984, 2016, 2048, 2080, 2112, 2144, 2176, 2208,
|
1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016, 2048, 2080, 2112, 2144, 2176, 2208,
|
||||||
2240, 2272, 2304, 2336, 2368, 2400, 2432, 2464, 2496, 2528, 2560,
|
2240, 2272, 2304, 2336, 2368, 2400, 2432, 2464, 2496, 2528, 2560, 2592, 2624, 2656,
|
||||||
2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816, 2848, 2880, 2912,
|
2688, 2720, 2752, 2784, 2816, 2848, 2880, 2912, 2944, 2976, 3008, 3040, 3072, 3104,
|
||||||
2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168, 3200, 3232, 3264,
|
3136, 3168, 3200, 3232, 3264, 3296, 3328, 3360, 3392, 3424, 3456, 3488, 3520, 3552,
|
||||||
3296, 3328, 3360, 3392, 3424, 3456, 3488, 3520, 3552, 3584, 3616,
|
3584, 3616, 3648, 3680, 3712, 3744, 3776, 3808, 3840, 3872, 3904, 3936, 3968, 4000,
|
||||||
3648, 3680, 3712, 3744, 3776, 3808, 3840, 3872, 3904, 3936, 3968,
|
4032, 4064, 4096, 4128, 4160, 4192, 4224, 4256, 4288, 4320, 4352, 4384, 4416, 4448,
|
||||||
4000, 4032, 4064, 4096, 4128, 4160, 4192, 4224, 4256, 4288, 4320,
|
4480, 4512, 4544, 4576, 4608, 4640, 4672, 4704, 4736, 4768, 4800, 4832, 4864, 4896,
|
||||||
4352, 4384, 4416, 4448, 4480, 4512, 4544, 4576, 4608, 4640, 4672,
|
4928, 4960, 4992, 5024, 5056, 5088, 5120, 5152, 5184, 5216, 5248, 5280, 5312, 5344,
|
||||||
4704, 4736, 4768, 4800, 4832, 4864, 4896, 4928, 4960, 4992, 5024,
|
5376, 5408, 5440, 5472, 5504, 5536, 5568, 5600, 5632, 5664, 5696, 5728, 5760, 5792,
|
||||||
5056, 5088, 5120, 5152, 5184, 5216, 5248, 5280, 5312, 5344, 5376,
|
5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080, 6112, 6144, 6176, 6208, 6240,
|
||||||
5408, 5440, 5472, 5504, 5536, 5568, 5600, 5632, 5664, 5696, 5728,
|
6272, 6304, 6336, 6368, 6400, 6432, 6464, 6496, 6528, 6560, 6592, 6624, 6656, 6688,
|
||||||
5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080,
|
6720, 6752, 6784, 6816, 6848, 6880, 6912, 6944, 6976, 7008, 7040, 7072, 7104, 7136,
|
||||||
6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432,
|
7168, 7200, 7232, 7264, 7296, 7328, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584,
|
||||||
6464, 6496, 6528, 6560, 6592, 6624, 6656, 6688, 6720, 6752, 6784,
|
7616, 7648, 7680, 7712, 7744, 7776, 7808, 7840, 7872, 7904, 7936, 7968, 8000, 8032,
|
||||||
6816, 6848, 6880, 6912, 6944, 6976, 7008, 7040, 7072, 7104, 7136,
|
8064, 8096, 8128, 8160};
|
||||||
7168, 7200, 7232, 7264, 7296, 7328, 7360, 7392, 7424, 7456, 7488,
|
|
||||||
7520, 7552, 7584, 7616, 7648, 7680, 7712, 7744, 7776, 7808, 7840,
|
|
||||||
7872, 7904, 7936, 7968, 8000, 8032, 8064, 8096, 8128, 8160 };
|
|
||||||
|
|
||||||
#define Cr_R Cb_B
|
#define Cr_R Cb_B
|
||||||
|
|
||||||
static INT16 Cr_G[] = { 0, -26, -53, -79, -106, -133, -160, -187,
|
static INT16 Cr_G[] = {
|
||||||
-213, -240, -267, -294, -321, -347, -374, -401, -428, -455, -481,
|
0, -26, -53, -79, -106, -133, -160, -187, -213, -240, -267, -294,
|
||||||
-508, -535, -562, -589, -615, -642, -669, -696, -722, -749, -776,
|
-321, -347, -374, -401, -428, -455, -481, -508, -535, -562, -589, -615,
|
||||||
-803, -830, -856, -883, -910, -937, -964, -990, -1017, -1044, -1071,
|
-642, -669, -696, -722, -749, -776, -803, -830, -856, -883, -910, -937,
|
||||||
-1098, -1124, -1151, -1178, -1205, -1232, -1258, -1285, -1312, -1339,
|
-964, -990, -1017, -1044, -1071, -1098, -1124, -1151, -1178, -1205, -1232, -1258,
|
||||||
-1366, -1392, -1419, -1446, -1473, -1500, -1526, -1553, -1580, -1607,
|
-1285, -1312, -1339, -1366, -1392, -1419, -1446, -1473, -1500, -1526, -1553, -1580,
|
||||||
-1634, -1660, -1687, -1714, -1741, -1768, -1794, -1821, -1848, -1875,
|
-1607, -1634, -1660, -1687, -1714, -1741, -1768, -1794, -1821, -1848, -1875, -1902,
|
||||||
-1902, -1928, -1955, -1982, -2009, -2036, -2062, -2089, -2116, -2143,
|
-1928, -1955, -1982, -2009, -2036, -2062, -2089, -2116, -2143, -2169, -2196, -2223,
|
||||||
-2169, -2196, -2223, -2250, -2277, -2303, -2330, -2357, -2384, -2411,
|
-2250, -2277, -2303, -2330, -2357, -2384, -2411, -2437, -2464, -2491, -2518, -2545,
|
||||||
-2437, -2464, -2491, -2518, -2545, -2571, -2598, -2625, -2652, -2679,
|
-2571, -2598, -2625, -2652, -2679, -2705, -2732, -2759, -2786, -2813, -2839, -2866,
|
||||||
-2705, -2732, -2759, -2786, -2813, -2839, -2866, -2893, -2920, -2947,
|
-2893, -2920, -2947, -2973, -3000, -3027, -3054, -3081, -3107, -3134, -3161, -3188,
|
||||||
-2973, -3000, -3027, -3054, -3081, -3107, -3134, -3161, -3188, -3215,
|
-3215, -3241, -3268, -3295, -3322, -3349, -3375, -3402, -3429, -3456, -3483, -3509,
|
||||||
-3241, -3268, -3295, -3322, -3349, -3375, -3402, -3429, -3456, -3483,
|
-3536, -3563, -3590, -3616, -3643, -3670, -3697, -3724, -3750, -3777, -3804, -3831,
|
||||||
-3509, -3536, -3563, -3590, -3616, -3643, -3670, -3697, -3724, -3750,
|
-3858, -3884, -3911, -3938, -3965, -3992, -4018, -4045, -4072, -4099, -4126, -4152,
|
||||||
-3777, -3804, -3831, -3858, -3884, -3911, -3938, -3965, -3992, -4018,
|
-4179, -4206, -4233, -4260, -4286, -4313, -4340, -4367, -4394, -4420, -4447, -4474,
|
||||||
-4045, -4072, -4099, -4126, -4152, -4179, -4206, -4233, -4260, -4286,
|
-4501, -4528, -4554, -4581, -4608, -4635, -4662, -4688, -4715, -4742, -4769, -4796,
|
||||||
-4313, -4340, -4367, -4394, -4420, -4447, -4474, -4501, -4528, -4554,
|
-4822, -4849, -4876, -4903, -4929, -4956, -4983, -5010, -5037, -5063, -5090, -5117,
|
||||||
-4581, -4608, -4635, -4662, -4688, -4715, -4742, -4769, -4796, -4822,
|
-5144, -5171, -5197, -5224, -5251, -5278, -5305, -5331, -5358, -5385, -5412, -5439,
|
||||||
-4849, -4876, -4903, -4929, -4956, -4983, -5010, -5037, -5063, -5090,
|
-5465, -5492, -5519, -5546, -5573, -5599, -5626, -5653, -5680, -5707, -5733, -5760,
|
||||||
-5117, -5144, -5171, -5197, -5224, -5251, -5278, -5305, -5331, -5358,
|
-5787, -5814, -5841, -5867, -5894, -5921, -5948, -5975, -6001, -6028, -6055, -6082,
|
||||||
-5385, -5412, -5439, -5465, -5492, -5519, -5546, -5573, -5599, -5626,
|
-6109, -6135, -6162, -6189, -6216, -6243, -6269, -6296, -6323, -6350, -6376, -6403,
|
||||||
-5653, -5680, -5707, -5733, -5760, -5787, -5814, -5841, -5867, -5894,
|
-6430, -6457, -6484, -6510, -6537, -6564, -6591, -6618, -6644, -6671, -6698, -6725,
|
||||||
-5921, -5948, -5975, -6001, -6028, -6055, -6082, -6109, -6135, -6162,
|
-6752, -6778, -6805, -6832};
|
||||||
-6189, -6216, -6243, -6269, -6296, -6323, -6350, -6376, -6403, -6430,
|
|
||||||
-6457, -6484, -6510, -6537, -6564, -6591, -6618, -6644, -6671, -6698,
|
|
||||||
-6725, -6752, -6778, -6805, -6832 };
|
|
||||||
|
|
||||||
static INT16 Cr_B[] = { 0, -4, -9, -15, -20, -25, -30, -35, -41, -46,
|
static INT16 Cr_B[] = {
|
||||||
-51, -56, -61, -67, -72, -77, -82, -87, -93, -98, -103, -108, -113,
|
0, -4, -9, -15, -20, -25, -30, -35, -41, -46, -51, -56,
|
||||||
-119, -124, -129, -134, -140, -145, -150, -155, -160, -166, -171,
|
-61, -67, -72, -77, -82, -87, -93, -98, -103, -108, -113, -119,
|
||||||
-176, -181, -186, -192, -197, -202, -207, -212, -218, -223, -228,
|
-124, -129, -134, -140, -145, -150, -155, -160, -166, -171, -176, -181,
|
||||||
-233, -238, -244, -249, -254, -259, -264, -270, -275, -280, -285,
|
-186, -192, -197, -202, -207, -212, -218, -223, -228, -233, -238, -244,
|
||||||
-290, -296, -301, -306, -311, -316, -322, -327, -332, -337, -342,
|
-249, -254, -259, -264, -270, -275, -280, -285, -290, -296, -301, -306,
|
||||||
-348, -353, -358, -363, -368, -374, -379, -384, -389, -394, -400,
|
-311, -316, -322, -327, -332, -337, -342, -348, -353, -358, -363, -368,
|
||||||
-405, -410, -415, -421, -426, -431, -436, -441, -447, -452, -457,
|
-374, -379, -384, -389, -394, -400, -405, -410, -415, -421, -426, -431,
|
||||||
-462, -467, -473, -478, -483, -488, -493, -499, -504, -509, -514,
|
-436, -441, -447, -452, -457, -462, -467, -473, -478, -483, -488, -493,
|
||||||
-519, -525, -530, -535, -540, -545, -551, -556, -561, -566, -571,
|
-499, -504, -509, -514, -519, -525, -530, -535, -540, -545, -551, -556,
|
||||||
-577, -582, -587, -592, -597, -603, -608, -613, -618, -623, -629,
|
-561, -566, -571, -577, -582, -587, -592, -597, -603, -608, -613, -618,
|
||||||
-634, -639, -644, -649, -655, -660, -665, -670, -675, -681, -686,
|
-623, -629, -634, -639, -644, -649, -655, -660, -665, -670, -675, -681,
|
||||||
-691, -696, -702, -707, -712, -717, -722, -728, -733, -738, -743,
|
-686, -691, -696, -702, -707, -712, -717, -722, -728, -733, -738, -743,
|
||||||
-748, -754, -759, -764, -769, -774, -780, -785, -790, -795, -800,
|
-748, -754, -759, -764, -769, -774, -780, -785, -790, -795, -800, -806,
|
||||||
-806, -811, -816, -821, -826, -832, -837, -842, -847, -852, -858,
|
-811, -816, -821, -826, -832, -837, -842, -847, -852, -858, -863, -868,
|
||||||
-863, -868, -873, -878, -884, -889, -894, -899, -904, -910, -915,
|
-873, -878, -884, -889, -894, -899, -904, -910, -915, -920, -925, -930,
|
||||||
-920, -925, -930, -936, -941, -946, -951, -957, -962, -967, -972,
|
-936, -941, -946, -951, -957, -962, -967, -972, -977, -983, -988, -993,
|
||||||
-977, -983, -988, -993, -998, -1003, -1009, -1014, -1019, -1024,
|
-998, -1003, -1009, -1014, -1019, -1024, -1029, -1035, -1040, -1045, -1050, -1055,
|
||||||
-1029, -1035, -1040, -1045, -1050, -1055, -1061, -1066, -1071, -1076,
|
-1061, -1066, -1071, -1076, -1081, -1087, -1092, -1097, -1102, -1107, -1113, -1118,
|
||||||
-1081, -1087, -1092, -1097, -1102, -1107, -1113, -1118, -1123, -1128,
|
-1123, -1128, -1133, -1139, -1144, -1149, -1154, -1159, -1165, -1170, -1175, -1180,
|
||||||
-1133, -1139, -1144, -1149, -1154, -1159, -1165, -1170, -1175, -1180,
|
-1185, -1191, -1196, -1201, -1206, -1211, -1217, -1222, -1227, -1232, -1238, -1243,
|
||||||
-1185, -1191, -1196, -1201, -1206, -1211, -1217, -1222, -1227, -1232,
|
-1248, -1253, -1258, -1264, -1269, -1274, -1279, -1284, -1290, -1295, -1300, -1305,
|
||||||
-1238, -1243, -1248, -1253, -1258, -1264, -1269, -1274, -1279, -1284,
|
-1310, -1316, -1321, -1326};
|
||||||
-1290, -1295, -1300, -1305, -1310, -1316, -1321, -1326 };
|
|
||||||
|
|
||||||
static INT16 R_Cr[] = { -11484, -11394, -11305, -11215, -11125,
|
static INT16 R_Cr[] = {
|
||||||
-11036, -10946, -10856, -10766, -10677, -10587, -10497, -10407,
|
-11484, -11394, -11305, -11215, -11125, -11036, -10946, -10856, -10766, -10677,
|
||||||
-10318, -10228, -10138, -10049, -9959, -9869, -9779, -9690, -9600,
|
-10587, -10497, -10407, -10318, -10228, -10138, -10049, -9959, -9869, -9779,
|
||||||
-9510, -9420, -9331, -9241, -9151, -9062, -8972, -8882, -8792, -8703,
|
-9690, -9600, -9510, -9420, -9331, -9241, -9151, -9062, -8972, -8882,
|
||||||
-8613, -8523, -8433, -8344, -8254, -8164, -8075, -7985, -7895, -7805,
|
-8792, -8703, -8613, -8523, -8433, -8344, -8254, -8164, -8075, -7985,
|
||||||
-7716, -7626, -7536, -7446, -7357, -7267, -7177, -7088, -6998, -6908,
|
-7895, -7805, -7716, -7626, -7536, -7446, -7357, -7267, -7177, -7088,
|
||||||
-6818, -6729, -6639, -6549, -6459, -6370, -6280, -6190, -6101, -6011,
|
-6998, -6908, -6818, -6729, -6639, -6549, -6459, -6370, -6280, -6190,
|
||||||
-5921, -5831, -5742, -5652, -5562, -5472, -5383, -5293, -5203, -5113,
|
-6101, -6011, -5921, -5831, -5742, -5652, -5562, -5472, -5383, -5293,
|
||||||
-5024, -4934, -4844, -4755, -4665, -4575, -4485, -4396, -4306, -4216,
|
-5203, -5113, -5024, -4934, -4844, -4755, -4665, -4575, -4485, -4396,
|
||||||
-4126, -4037, -3947, -3857, -3768, -3678, -3588, -3498, -3409, -3319,
|
-4306, -4216, -4126, -4037, -3947, -3857, -3768, -3678, -3588, -3498,
|
||||||
-3229, -3139, -3050, -2960, -2870, -2781, -2691, -2601, -2511, -2422,
|
-3409, -3319, -3229, -3139, -3050, -2960, -2870, -2781, -2691, -2601,
|
||||||
-2332, -2242, -2152, -2063, -1973, -1883, -1794, -1704, -1614, -1524,
|
-2511, -2422, -2332, -2242, -2152, -2063, -1973, -1883, -1794, -1704,
|
||||||
-1435, -1345, -1255, -1165, -1076, -986, -896, -807, -717, -627, -537,
|
-1614, -1524, -1435, -1345, -1255, -1165, -1076, -986, -896, -807,
|
||||||
-448, -358, -268, -178, -89, 0, 90, 179, 269, 359, 449, 538, 628, 718,
|
-717, -627, -537, -448, -358, -268, -178, -89, 0, 90,
|
||||||
808, 897, 987, 1077, 1166, 1256, 1346, 1436, 1525, 1615, 1705, 1795,
|
179, 269, 359, 449, 538, 628, 718, 808, 897, 987,
|
||||||
1884, 1974, 2064, 2153, 2243, 2333, 2423, 2512, 2602, 2692, 2782,
|
1077, 1166, 1256, 1346, 1436, 1525, 1615, 1705, 1795, 1884,
|
||||||
2871, 2961, 3051, 3140, 3230, 3320, 3410, 3499, 3589, 3679, 3769,
|
1974, 2064, 2153, 2243, 2333, 2423, 2512, 2602, 2692, 2782,
|
||||||
3858, 3948, 4038, 4127, 4217, 4307, 4397, 4486, 4576, 4666, 4756,
|
2871, 2961, 3051, 3140, 3230, 3320, 3410, 3499, 3589, 3679,
|
||||||
4845, 4935, 5025, 5114, 5204, 5294, 5384, 5473, 5563, 5653, 5743,
|
3769, 3858, 3948, 4038, 4127, 4217, 4307, 4397, 4486, 4576,
|
||||||
5832, 5922, 6012, 6102, 6191, 6281, 6371, 6460, 6550, 6640, 6730,
|
4666, 4756, 4845, 4935, 5025, 5114, 5204, 5294, 5384, 5473,
|
||||||
6819, 6909, 6999, 7089, 7178, 7268, 7358, 7447, 7537, 7627, 7717,
|
5563, 5653, 5743, 5832, 5922, 6012, 6102, 6191, 6281, 6371,
|
||||||
7806, 7896, 7986, 8076, 8165, 8255, 8345, 8434, 8524, 8614, 8704,
|
6460, 6550, 6640, 6730, 6819, 6909, 6999, 7089, 7178, 7268,
|
||||||
8793, 8883, 8973, 9063, 9152, 9242, 9332, 9421, 9511, 9601, 9691,
|
7358, 7447, 7537, 7627, 7717, 7806, 7896, 7986, 8076, 8165,
|
||||||
9780, 9870, 9960, 10050, 10139, 10229, 10319, 10408, 10498, 10588,
|
8255, 8345, 8434, 8524, 8614, 8704, 8793, 8883, 8973, 9063,
|
||||||
10678, 10767, 10857, 10947, 11037, 11126, 11216, 11306, 11395 };
|
9152, 9242, 9332, 9421, 9511, 9601, 9691, 9780, 9870, 9960,
|
||||||
|
10050, 10139, 10229, 10319, 10408, 10498, 10588, 10678, 10767, 10857,
|
||||||
|
10947, 11037, 11126, 11216, 11306, 11395};
|
||||||
|
|
||||||
static INT16 G_Cb[] = { 2819, 2797, 2775, 2753, 2731, 2709, 2687,
|
static INT16 G_Cb[] = {
|
||||||
2665, 2643, 2621, 2599, 2577, 2555, 2533, 2511, 2489, 2467, 2445,
|
2819, 2797, 2775, 2753, 2731, 2709, 2687, 2665, 2643, 2621, 2599, 2577,
|
||||||
2423, 2401, 2379, 2357, 2335, 2313, 2291, 2269, 2247, 2225, 2202,
|
2555, 2533, 2511, 2489, 2467, 2445, 2423, 2401, 2379, 2357, 2335, 2313,
|
||||||
2180, 2158, 2136, 2114, 2092, 2070, 2048, 2026, 2004, 1982, 1960,
|
2291, 2269, 2247, 2225, 2202, 2180, 2158, 2136, 2114, 2092, 2070, 2048,
|
||||||
1938, 1916, 1894, 1872, 1850, 1828, 1806, 1784, 1762, 1740, 1718,
|
2026, 2004, 1982, 1960, 1938, 1916, 1894, 1872, 1850, 1828, 1806, 1784,
|
||||||
1696, 1674, 1652, 1630, 1608, 1586, 1564, 1542, 1520, 1498, 1476,
|
1762, 1740, 1718, 1696, 1674, 1652, 1630, 1608, 1586, 1564, 1542, 1520,
|
||||||
1454, 1432, 1410, 1388, 1366, 1344, 1321, 1299, 1277, 1255, 1233,
|
1498, 1476, 1454, 1432, 1410, 1388, 1366, 1344, 1321, 1299, 1277, 1255,
|
||||||
1211, 1189, 1167, 1145, 1123, 1101, 1079, 1057, 1035, 1013, 991, 969,
|
1233, 1211, 1189, 1167, 1145, 1123, 1101, 1079, 1057, 1035, 1013, 991,
|
||||||
947, 925, 903, 881, 859, 837, 815, 793, 771, 749, 727, 705, 683, 661,
|
969, 947, 925, 903, 881, 859, 837, 815, 793, 771, 749, 727,
|
||||||
639, 617, 595, 573, 551, 529, 507, 485, 463, 440, 418, 396, 374, 352,
|
705, 683, 661, 639, 617, 595, 573, 551, 529, 507, 485, 463,
|
||||||
330, 308, 286, 264, 242, 220, 198, 176, 154, 132, 110, 88, 66, 44, 22,
|
440, 418, 396, 374, 352, 330, 308, 286, 264, 242, 220, 198,
|
||||||
0, -21, -43, -65, -87, -109, -131, -153, -175, -197, -219, -241, -263,
|
176, 154, 132, 110, 88, 66, 44, 22, 0, -21, -43, -65,
|
||||||
-285, -307, -329, -351, -373, -395, -417, -439, -462, -484, -506,
|
-87, -109, -131, -153, -175, -197, -219, -241, -263, -285, -307, -329,
|
||||||
-528, -550, -572, -594, -616, -638, -660, -682, -704, -726, -748,
|
-351, -373, -395, -417, -439, -462, -484, -506, -528, -550, -572, -594,
|
||||||
-770, -792, -814, -836, -858, -880, -902, -924, -946, -968, -990,
|
-616, -638, -660, -682, -704, -726, -748, -770, -792, -814, -836, -858,
|
||||||
-1012, -1034, -1056, -1078, -1100, -1122, -1144, -1166, -1188, -1210,
|
-880, -902, -924, -946, -968, -990, -1012, -1034, -1056, -1078, -1100, -1122,
|
||||||
-1232, -1254, -1276, -1298, -1320, -1343, -1365, -1387, -1409, -1431,
|
-1144, -1166, -1188, -1210, -1232, -1254, -1276, -1298, -1320, -1343, -1365, -1387,
|
||||||
-1453, -1475, -1497, -1519, -1541, -1563, -1585, -1607, -1629, -1651,
|
-1409, -1431, -1453, -1475, -1497, -1519, -1541, -1563, -1585, -1607, -1629, -1651,
|
||||||
-1673, -1695, -1717, -1739, -1761, -1783, -1805, -1827, -1849, -1871,
|
-1673, -1695, -1717, -1739, -1761, -1783, -1805, -1827, -1849, -1871, -1893, -1915,
|
||||||
-1893, -1915, -1937, -1959, -1981, -2003, -2025, -2047, -2069, -2091,
|
-1937, -1959, -1981, -2003, -2025, -2047, -2069, -2091, -2113, -2135, -2157, -2179,
|
||||||
-2113, -2135, -2157, -2179, -2201, -2224, -2246, -2268, -2290, -2312,
|
-2201, -2224, -2246, -2268, -2290, -2312, -2334, -2356, -2378, -2400, -2422, -2444,
|
||||||
-2334, -2356, -2378, -2400, -2422, -2444, -2466, -2488, -2510, -2532,
|
-2466, -2488, -2510, -2532, -2554, -2576, -2598, -2620, -2642, -2664, -2686, -2708,
|
||||||
-2554, -2576, -2598, -2620, -2642, -2664, -2686, -2708, -2730, -2752,
|
-2730, -2752, -2774, -2796};
|
||||||
-2774, -2796 };
|
|
||||||
|
|
||||||
static INT16 G_Cr[] = { 5850, 5805, 5759, 5713, 5667, 5622, 5576,
|
static INT16 G_Cr[] = {
|
||||||
5530, 5485, 5439, 5393, 5347, 5302, 5256, 5210, 5165, 5119, 5073,
|
5850, 5805, 5759, 5713, 5667, 5622, 5576, 5530, 5485, 5439, 5393, 5347,
|
||||||
5028, 4982, 4936, 4890, 4845, 4799, 4753, 4708, 4662, 4616, 4570,
|
5302, 5256, 5210, 5165, 5119, 5073, 5028, 4982, 4936, 4890, 4845, 4799,
|
||||||
4525, 4479, 4433, 4388, 4342, 4296, 4251, 4205, 4159, 4113, 4068,
|
4753, 4708, 4662, 4616, 4570, 4525, 4479, 4433, 4388, 4342, 4296, 4251,
|
||||||
4022, 3976, 3931, 3885, 3839, 3794, 3748, 3702, 3656, 3611, 3565,
|
4205, 4159, 4113, 4068, 4022, 3976, 3931, 3885, 3839, 3794, 3748, 3702,
|
||||||
3519, 3474, 3428, 3382, 3336, 3291, 3245, 3199, 3154, 3108, 3062,
|
3656, 3611, 3565, 3519, 3474, 3428, 3382, 3336, 3291, 3245, 3199, 3154,
|
||||||
3017, 2971, 2925, 2879, 2834, 2788, 2742, 2697, 2651, 2605, 2559,
|
3108, 3062, 3017, 2971, 2925, 2879, 2834, 2788, 2742, 2697, 2651, 2605,
|
||||||
2514, 2468, 2422, 2377, 2331, 2285, 2240, 2194, 2148, 2102, 2057,
|
2559, 2514, 2468, 2422, 2377, 2331, 2285, 2240, 2194, 2148, 2102, 2057,
|
||||||
2011, 1965, 1920, 1874, 1828, 1782, 1737, 1691, 1645, 1600, 1554,
|
2011, 1965, 1920, 1874, 1828, 1782, 1737, 1691, 1645, 1600, 1554, 1508,
|
||||||
1508, 1463, 1417, 1371, 1325, 1280, 1234, 1188, 1143, 1097, 1051,
|
1463, 1417, 1371, 1325, 1280, 1234, 1188, 1143, 1097, 1051, 1006, 960,
|
||||||
1006, 960, 914, 868, 823, 777, 731, 686, 640, 594, 548, 503, 457, 411,
|
914, 868, 823, 777, 731, 686, 640, 594, 548, 503, 457, 411,
|
||||||
366, 320, 274, 229, 183, 137, 91, 46, 0, -45, -90, -136, -182, -228,
|
366, 320, 274, 229, 183, 137, 91, 46, 0, -45, -90, -136,
|
||||||
-273, -319, -365, -410, -456, -502, -547, -593, -639, -685, -730,
|
-182, -228, -273, -319, -365, -410, -456, -502, -547, -593, -639, -685,
|
||||||
-776, -822, -867, -913, -959, -1005, -1050, -1096, -1142, -1187,
|
-730, -776, -822, -867, -913, -959, -1005, -1050, -1096, -1142, -1187, -1233,
|
||||||
-1233, -1279, -1324, -1370, -1416, -1462, -1507, -1553, -1599, -1644,
|
-1279, -1324, -1370, -1416, -1462, -1507, -1553, -1599, -1644, -1690, -1736, -1781,
|
||||||
-1690, -1736, -1781, -1827, -1873, -1919, -1964, -2010, -2056, -2101,
|
-1827, -1873, -1919, -1964, -2010, -2056, -2101, -2147, -2193, -2239, -2284, -2330,
|
||||||
-2147, -2193, -2239, -2284, -2330, -2376, -2421, -2467, -2513, -2558,
|
-2376, -2421, -2467, -2513, -2558, -2604, -2650, -2696, -2741, -2787, -2833, -2878,
|
||||||
-2604, -2650, -2696, -2741, -2787, -2833, -2878, -2924, -2970, -3016,
|
-2924, -2970, -3016, -3061, -3107, -3153, -3198, -3244, -3290, -3335, -3381, -3427,
|
||||||
-3061, -3107, -3153, -3198, -3244, -3290, -3335, -3381, -3427, -3473,
|
-3473, -3518, -3564, -3610, -3655, -3701, -3747, -3793, -3838, -3884, -3930, -3975,
|
||||||
-3518, -3564, -3610, -3655, -3701, -3747, -3793, -3838, -3884, -3930,
|
-4021, -4067, -4112, -4158, -4204, -4250, -4295, -4341, -4387, -4432, -4478, -4524,
|
||||||
-3975, -4021, -4067, -4112, -4158, -4204, -4250, -4295, -4341, -4387,
|
-4569, -4615, -4661, -4707, -4752, -4798, -4844, -4889, -4935, -4981, -5027, -5072,
|
||||||
-4432, -4478, -4524, -4569, -4615, -4661, -4707, -4752, -4798, -4844,
|
-5118, -5164, -5209, -5255, -5301, -5346, -5392, -5438, -5484, -5529, -5575, -5621,
|
||||||
-4889, -4935, -4981, -5027, -5072, -5118, -5164, -5209, -5255, -5301,
|
-5666, -5712, -5758, -5804};
|
||||||
-5346, -5392, -5438, -5484, -5529, -5575, -5621, -5666, -5712, -5758,
|
|
||||||
-5804 };
|
|
||||||
|
|
||||||
static INT16 B_Cb[] = { -14515, -14402, -14288, -14175, -14062,
|
|
||||||
-13948, -13835, -13721, -13608, -13495, -13381, -13268, -13154,
|
|
||||||
-13041, -12928, -12814, -12701, -12587, -12474, -12360, -12247,
|
|
||||||
-12134, -12020, -11907, -11793, -11680, -11567, -11453, -11340,
|
|
||||||
-11226, -11113, -11000, -10886, -10773, -10659, -10546, -10433,
|
|
||||||
-10319, -10206, -10092, -9979, -9865, -9752, -9639, -9525, -9412,
|
|
||||||
-9298, -9185, -9072, -8958, -8845, -8731, -8618, -8505, -8391, -8278,
|
|
||||||
-8164, -8051, -7938, -7824, -7711, -7597, -7484, -7371, -7257, -7144,
|
|
||||||
-7030, -6917, -6803, -6690, -6577, -6463, -6350, -6236, -6123, -6010,
|
|
||||||
-5896, -5783, -5669, -5556, -5443, -5329, -5216, -5102, -4989, -4876,
|
|
||||||
-4762, -4649, -4535, -4422, -4309, -4195, -4082, -3968, -3855, -3741,
|
|
||||||
-3628, -3515, -3401, -3288, -3174, -3061, -2948, -2834, -2721, -2607,
|
|
||||||
-2494, -2381, -2267, -2154, -2040, -1927, -1814, -1700, -1587, -1473,
|
|
||||||
-1360, -1246, -1133, -1020, -906, -793, -679, -566, -453, -339, -226,
|
|
||||||
-112, 0, 113, 227, 340, 454, 567, 680, 794, 907, 1021, 1134, 1247,
|
|
||||||
1361, 1474, 1588, 1701, 1815, 1928, 2041, 2155, 2268, 2382, 2495,
|
|
||||||
2608, 2722, 2835, 2949, 3062, 3175, 3289, 3402, 3516, 3629, 3742,
|
|
||||||
3856, 3969, 4083, 4196, 4310, 4423, 4536, 4650, 4763, 4877, 4990,
|
|
||||||
5103, 5217, 5330, 5444, 5557, 5670, 5784, 5897, 6011, 6124, 6237,
|
|
||||||
6351, 6464, 6578, 6691, 6804, 6918, 7031, 7145, 7258, 7372, 7485,
|
|
||||||
7598, 7712, 7825, 7939, 8052, 8165, 8279, 8392, 8506, 8619, 8732,
|
|
||||||
8846, 8959, 9073, 9186, 9299, 9413, 9526, 9640, 9753, 9866, 9980,
|
|
||||||
10093, 10207, 10320, 10434, 10547, 10660, 10774, 10887, 11001, 11114,
|
|
||||||
11227, 11341, 11454, 11568, 11681, 11794, 11908, 12021, 12135, 12248,
|
|
||||||
12361, 12475, 12588, 12702, 12815, 12929, 13042, 13155, 13269, 13382,
|
|
||||||
13496, 13609, 13722, 13836, 13949, 14063, 14176, 14289, 14403 };
|
|
||||||
|
|
||||||
|
static INT16 B_Cb[] = {
|
||||||
|
-14515, -14402, -14288, -14175, -14062, -13948, -13835, -13721, -13608, -13495,
|
||||||
|
-13381, -13268, -13154, -13041, -12928, -12814, -12701, -12587, -12474, -12360,
|
||||||
|
-12247, -12134, -12020, -11907, -11793, -11680, -11567, -11453, -11340, -11226,
|
||||||
|
-11113, -11000, -10886, -10773, -10659, -10546, -10433, -10319, -10206, -10092,
|
||||||
|
-9979, -9865, -9752, -9639, -9525, -9412, -9298, -9185, -9072, -8958,
|
||||||
|
-8845, -8731, -8618, -8505, -8391, -8278, -8164, -8051, -7938, -7824,
|
||||||
|
-7711, -7597, -7484, -7371, -7257, -7144, -7030, -6917, -6803, -6690,
|
||||||
|
-6577, -6463, -6350, -6236, -6123, -6010, -5896, -5783, -5669, -5556,
|
||||||
|
-5443, -5329, -5216, -5102, -4989, -4876, -4762, -4649, -4535, -4422,
|
||||||
|
-4309, -4195, -4082, -3968, -3855, -3741, -3628, -3515, -3401, -3288,
|
||||||
|
-3174, -3061, -2948, -2834, -2721, -2607, -2494, -2381, -2267, -2154,
|
||||||
|
-2040, -1927, -1814, -1700, -1587, -1473, -1360, -1246, -1133, -1020,
|
||||||
|
-906, -793, -679, -566, -453, -339, -226, -112, 0, 113,
|
||||||
|
227, 340, 454, 567, 680, 794, 907, 1021, 1134, 1247,
|
||||||
|
1361, 1474, 1588, 1701, 1815, 1928, 2041, 2155, 2268, 2382,
|
||||||
|
2495, 2608, 2722, 2835, 2949, 3062, 3175, 3289, 3402, 3516,
|
||||||
|
3629, 3742, 3856, 3969, 4083, 4196, 4310, 4423, 4536, 4650,
|
||||||
|
4763, 4877, 4990, 5103, 5217, 5330, 5444, 5557, 5670, 5784,
|
||||||
|
5897, 6011, 6124, 6237, 6351, 6464, 6578, 6691, 6804, 6918,
|
||||||
|
7031, 7145, 7258, 7372, 7485, 7598, 7712, 7825, 7939, 8052,
|
||||||
|
8165, 8279, 8392, 8506, 8619, 8732, 8846, 8959, 9073, 9186,
|
||||||
|
9299, 9413, 9526, 9640, 9753, 9866, 9980, 10093, 10207, 10320,
|
||||||
|
10434, 10547, 10660, 10774, 10887, 11001, 11114, 11227, 11341, 11454,
|
||||||
|
11568, 11681, 11794, 11908, 12021, 12135, 12248, 12361, 12475, 12588,
|
||||||
|
12702, 12815, 12929, 13042, 13155, 13269, 13382, 13496, 13609, 13722,
|
||||||
|
13836, 13949, 14063, 14176, 14289, 14403};
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels)
|
ImagingConvertRGB2YCbCr(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int x;
|
int x;
|
||||||
UINT8 a;
|
UINT8 a;
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
int y, cr, cb;
|
int y, cr, cb;
|
||||||
|
|
||||||
for (x = 0; x < pixels; x++, in += 4, out += 4) {
|
for (x = 0; x < pixels; x++, in += 4, out += 4) {
|
||||||
|
|
||||||
r = in[0];
|
r = in[0];
|
||||||
g = in[1];
|
g = in[1];
|
||||||
b = in[2];
|
b = in[2];
|
||||||
|
@ -361,15 +339,13 @@ ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingConvertYCbCr2RGB(UINT8* out, const UINT8* in, int pixels)
|
ImagingConvertYCbCr2RGB(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int x;
|
int x;
|
||||||
UINT8 a;
|
UINT8 a;
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
int y, cr, cb;
|
int y, cr, cb;
|
||||||
|
|
||||||
for (x = 0; x < pixels; x++, in += 4, out += 4) {
|
for (x = 0; x < pixels; x++, in += 4, out += 4) {
|
||||||
|
|
||||||
y = in[0];
|
y = in[0];
|
||||||
cb = in[1];
|
cb = in[1];
|
||||||
cr = in[2];
|
cr = in[2];
|
||||||
|
|
|
@ -15,13 +15,10 @@
|
||||||
* See the README file for details on usage and redistribution.
|
* See the README file for details on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
static Imaging
|
static Imaging
|
||||||
_copy(Imaging imOut, Imaging imIn)
|
_copy(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
|
@ -50,13 +47,11 @@ _copy(Imaging imOut, Imaging imIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingCopy(Imaging imIn)
|
ImagingCopy(Imaging imIn) {
|
||||||
{
|
|
||||||
return _copy(NULL, imIn);
|
return _copy(NULL, imIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingCopy2(Imaging imOut, Imaging imIn)
|
ImagingCopy2(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
return _copy(imOut, imIn);
|
return _copy(imOut, imIn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,10 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingCrop(Imaging imIn, int sx0, int sy0, int sx1, int sy1)
|
ImagingCrop(Imaging imIn, int sx0, int sy0, int sx1, int sy1) {
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int xsize, ysize;
|
int xsize, ysize;
|
||||||
int dx0, dy0, dx1, dy1;
|
int dx0, dy0, dx1, dy1;
|
||||||
|
|
|
@ -19,17 +19,14 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include "ImDib.h"
|
#include "ImDib.h"
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
ImagingGetModeDIB(int size_out[2])
|
ImagingGetModeDIB(int size_out[2]) {
|
||||||
{
|
|
||||||
/* Get device characteristics */
|
/* Get device characteristics */
|
||||||
|
|
||||||
HDC dc;
|
HDC dc;
|
||||||
|
@ -55,10 +52,8 @@ ImagingGetModeDIB(int size_out[2])
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ImagingDIB
|
ImagingDIB
|
||||||
ImagingNewDIB(const char *mode, int xsize, int ysize)
|
ImagingNewDIB(const char *mode, int xsize, int ysize) {
|
||||||
{
|
|
||||||
/* Create a Windows bitmap */
|
/* Create a Windows bitmap */
|
||||||
|
|
||||||
ImagingDIB dib;
|
ImagingDIB dib;
|
||||||
|
@ -66,8 +61,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Check mode */
|
/* Check mode */
|
||||||
if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 &&
|
if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 && strcmp(mode, "RGB") != 0) {
|
||||||
strcmp(mode, "RGB") != 0) {
|
|
||||||
return (ImagingDIB)ImagingError_ModeError();
|
return (ImagingDIB)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,8 +72,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
return (ImagingDIB)ImagingError_MemoryError();
|
return (ImagingDIB)ImagingError_MemoryError();
|
||||||
}
|
}
|
||||||
/* malloc check ok, small constant allocation */
|
/* malloc check ok, small constant allocation */
|
||||||
dib->info = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) +
|
dib->info = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
||||||
256 * sizeof(RGBQUAD));
|
|
||||||
if (!dib->info) {
|
if (!dib->info) {
|
||||||
free(dib);
|
free(dib);
|
||||||
return (ImagingDIB)ImagingError_MemoryError();
|
return (ImagingDIB)ImagingError_MemoryError();
|
||||||
|
@ -101,8 +94,8 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
return (ImagingDIB)ImagingError_MemoryError();
|
return (ImagingDIB)ImagingError_MemoryError();
|
||||||
}
|
}
|
||||||
|
|
||||||
dib->bitmap = CreateDIBSection(dib->dc, dib->info, DIB_RGB_COLORS,
|
dib->bitmap =
|
||||||
&dib->bits, NULL, 0);
|
CreateDIBSection(dib->dc, dib->info, DIB_RGB_COLORS, &dib->bits, NULL, 0);
|
||||||
if (!dib->bitmap) {
|
if (!dib->bitmap) {
|
||||||
free(dib->info);
|
free(dib->info);
|
||||||
free(dib);
|
free(dib);
|
||||||
|
@ -131,9 +124,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
/* Bind a palette to it as well (only required for 8-bit DIBs) */
|
/* Bind a palette to it as well (only required for 8-bit DIBs) */
|
||||||
if (dib->pixelsize == 1) {
|
if (dib->pixelsize == 1) {
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
palette[i].rgbRed =
|
palette[i].rgbRed = palette[i].rgbGreen = palette[i].rgbBlue = i;
|
||||||
palette[i].rgbGreen =
|
|
||||||
palette[i].rgbBlue = i;
|
|
||||||
palette[i].rgbReserved = 0;
|
palette[i].rgbReserved = 0;
|
||||||
}
|
}
|
||||||
SetDIBColorTable(dib->dc, 0, 256, palette);
|
SetDIBColorTable(dib->dc, 0, 256, palette);
|
||||||
|
@ -141,7 +132,6 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
|
|
||||||
/* Create an associated palette (for 8-bit displays only) */
|
/* Create an associated palette (for 8-bit displays only) */
|
||||||
if (strcmp(ImagingGetModeDIB(NULL), "P") == 0) {
|
if (strcmp(ImagingGetModeDIB(NULL), "P") == 0) {
|
||||||
|
|
||||||
char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
|
char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
|
||||||
LPLOGPALETTE pal = (LPLOGPALETTE)palbuf;
|
LPLOGPALETTE pal = (LPLOGPALETTE)palbuf;
|
||||||
int i, r, g, b;
|
int i, r, g, b;
|
||||||
|
@ -152,7 +142,6 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
GetSystemPaletteEntries(dib->dc, 0, 256, pal->palPalEntry);
|
GetSystemPaletteEntries(dib->dc, 0, 256, pal->palPalEntry);
|
||||||
|
|
||||||
if (strcmp(mode, "L") == 0) {
|
if (strcmp(mode, "L") == 0) {
|
||||||
|
|
||||||
/* Greyscale DIB. Fill all 236 slots with a greyscale ramp
|
/* Greyscale DIB. Fill all 236 slots with a greyscale ramp
|
||||||
* (this is usually overkill on Windows since VGA only offers
|
* (this is usually overkill on Windows since VGA only offers
|
||||||
* 6 bits greyscale resolution). Ignore the slots already
|
* 6 bits greyscale resolution). Ignore the slots already
|
||||||
|
@ -160,8 +149,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
|
|
||||||
i = 10;
|
i = 10;
|
||||||
for (r = 0; r < 236; r++) {
|
for (r = 0; r < 236; r++) {
|
||||||
pal->palPalEntry[i].peRed =
|
pal->palPalEntry[i].peRed = pal->palPalEntry[i].peGreen =
|
||||||
pal->palPalEntry[i].peGreen =
|
|
||||||
pal->palPalEntry[i].peBlue = i;
|
pal->palPalEntry[i].peBlue = i;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +157,6 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
dib->palette = CreatePalette(pal);
|
dib->palette = CreatePalette(pal);
|
||||||
|
|
||||||
} else if (strcmp(mode, "RGB") == 0) {
|
} else if (strcmp(mode, "RGB") == 0) {
|
||||||
|
|
||||||
#ifdef CUBE216
|
#ifdef CUBE216
|
||||||
|
|
||||||
/* Colour DIB. Create a 6x6x6 colour cube (216 entries) and
|
/* Colour DIB. Create a 6x6x6 colour cube (216 entries) and
|
||||||
|
@ -189,8 +176,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
}
|
}
|
||||||
for (r = 1; r < 22 - 1; r++) {
|
for (r = 1; r < 22 - 1; r++) {
|
||||||
/* Black and white are already provided by the cube. */
|
/* Black and white are already provided by the cube. */
|
||||||
pal->palPalEntry[i].peRed =
|
pal->palPalEntry[i].peRed = pal->palPalEntry[i].peGreen =
|
||||||
pal->palPalEntry[i].peGreen =
|
|
||||||
pal->palPalEntry[i].peBlue = r * 255 / (22 - 1);
|
pal->palPalEntry[i].peBlue = r * 255 / (22 - 1);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -214,32 +200,30 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dib->palette = CreatePalette(pal);
|
dib->palette = CreatePalette(pal);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dib;
|
return dib;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4])
|
ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]) {
|
||||||
{
|
|
||||||
/* Paste image data into a bitmap */
|
/* Paste image data into a bitmap */
|
||||||
|
|
||||||
/* FIXME: check size! */
|
/* FIXME: check size! */
|
||||||
|
|
||||||
int y;
|
int y;
|
||||||
for (y = 0; y < im->ysize; y++) {
|
for (y = 0; y < im->ysize; y++) {
|
||||||
dib->pack(dib->bits + dib->linesize*(dib->ysize-(xy[1]+y)-1) +
|
dib->pack(
|
||||||
xy[0]*dib->pixelsize, im->image[y], im->xsize);
|
dib->bits + dib->linesize * (dib->ysize - (xy[1] + y) - 1) +
|
||||||
|
xy[0] * dib->pixelsize,
|
||||||
|
im->image[y],
|
||||||
|
im->xsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingExposeDIB(ImagingDIB dib, void *dc)
|
ImagingExposeDIB(ImagingDIB dib, void *dc) {
|
||||||
{
|
|
||||||
/* Copy bitmap to display */
|
/* Copy bitmap to display */
|
||||||
|
|
||||||
if (dib->palette != 0) {
|
if (dib->palette != 0) {
|
||||||
|
@ -249,35 +233,52 @@ ImagingExposeDIB(ImagingDIB dib, void *dc)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingDrawDIB(ImagingDIB dib, void *dc, int dst[4], int src[4])
|
ImagingDrawDIB(ImagingDIB dib, void *dc, int dst[4], int src[4]) {
|
||||||
{
|
|
||||||
/* Copy bitmap to printer/display */
|
/* Copy bitmap to printer/display */
|
||||||
|
|
||||||
if (GetDeviceCaps((HDC)dc, RASTERCAPS) & RC_STRETCHDIB) {
|
if (GetDeviceCaps((HDC)dc, RASTERCAPS) & RC_STRETCHDIB) {
|
||||||
/* stretchdib (printers) */
|
/* stretchdib (printers) */
|
||||||
StretchDIBits((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1],
|
StretchDIBits(
|
||||||
src[0], src[1], src[2]-src[0], src[3]-src[1], dib->bits,
|
(HDC)dc,
|
||||||
dib->info, DIB_RGB_COLORS, SRCCOPY);
|
dst[0],
|
||||||
|
dst[1],
|
||||||
|
dst[2] - dst[0],
|
||||||
|
dst[3] - dst[1],
|
||||||
|
src[0],
|
||||||
|
src[1],
|
||||||
|
src[2] - src[0],
|
||||||
|
src[3] - src[1],
|
||||||
|
dib->bits,
|
||||||
|
dib->info,
|
||||||
|
DIB_RGB_COLORS,
|
||||||
|
SRCCOPY);
|
||||||
} else {
|
} else {
|
||||||
/* stretchblt (displays) */
|
/* stretchblt (displays) */
|
||||||
if (dib->palette != 0) {
|
if (dib->palette != 0) {
|
||||||
SelectPalette((HDC)dc, dib->palette, FALSE);
|
SelectPalette((HDC)dc, dib->palette, FALSE);
|
||||||
}
|
}
|
||||||
StretchBlt((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1],
|
StretchBlt(
|
||||||
dib->dc, src[0], src[1], src[2]-src[0], src[3]-src[1],
|
(HDC)dc,
|
||||||
|
dst[0],
|
||||||
|
dst[1],
|
||||||
|
dst[2] - dst[0],
|
||||||
|
dst[3] - dst[1],
|
||||||
|
dib->dc,
|
||||||
|
src[0],
|
||||||
|
src[1],
|
||||||
|
src[2] - src[0],
|
||||||
|
src[3] - src[1],
|
||||||
SRCCOPY);
|
SRCCOPY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingQueryPaletteDIB(ImagingDIB dib, void *dc)
|
ImagingQueryPaletteDIB(ImagingDIB dib, void *dc) {
|
||||||
{
|
|
||||||
/* Install bitmap palette */
|
/* Install bitmap palette */
|
||||||
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (dib->palette != 0) {
|
if (dib->palette != 0) {
|
||||||
|
|
||||||
/* Realize associated palette */
|
/* Realize associated palette */
|
||||||
HPALETTE now = SelectPalette((HDC)dc, dib->palette, FALSE);
|
HPALETTE now = SelectPalette((HDC)dc, dib->palette, FALSE);
|
||||||
n = RealizePalette((HDC)dc);
|
n = RealizePalette((HDC)dc);
|
||||||
|
@ -293,8 +294,7 @@ ImagingQueryPaletteDIB(ImagingDIB dib, void *dc)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingDeleteDIB(ImagingDIB dib)
|
ImagingDeleteDIB(ImagingDIB dib) {
|
||||||
{
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
|
|
||||||
if (dib->palette) {
|
if (dib->palette) {
|
||||||
|
|
|
@ -65,8 +65,7 @@ typedef struct {
|
||||||
typedef void (*hline_handler)(Imaging, int, int, int, int);
|
typedef void (*hline_handler)(Imaging, int, int, int, int);
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
point8(Imaging im, int x, int y, int ink)
|
point8(Imaging im, int x, int y, int ink) {
|
||||||
{
|
|
||||||
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
|
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
|
||||||
if (strncmp(im->mode, "I;16", 4) == 0) {
|
if (strncmp(im->mode, "I;16", 4) == 0) {
|
||||||
im->image8[y][x * 2] = (UINT8)ink;
|
im->image8[y][x * 2] = (UINT8)ink;
|
||||||
|
@ -78,16 +77,14 @@ point8(Imaging im, int x, int y, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
point32(Imaging im, int x, int y, int ink)
|
point32(Imaging im, int x, int y, int ink) {
|
||||||
{
|
|
||||||
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
|
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
|
||||||
im->image32[y][x] = ink;
|
im->image32[y][x] = ink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
point32rgba(Imaging im, int x, int y, int ink)
|
point32rgba(Imaging im, int x, int y, int ink) {
|
||||||
{
|
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
|
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
|
||||||
|
@ -100,8 +97,7 @@ point32rgba(Imaging im, int x, int y, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
hline8(Imaging im, int x0, int y0, int x1, int ink)
|
hline8(Imaging im, int x0, int y0, int x1, int ink) {
|
||||||
{
|
|
||||||
int tmp, pixelwidth;
|
int tmp, pixelwidth;
|
||||||
|
|
||||||
if (y0 >= 0 && y0 < im->ysize) {
|
if (y0 >= 0 && y0 < im->ysize) {
|
||||||
|
@ -120,15 +116,16 @@ hline8(Imaging im, int x0, int y0, int x1, int ink)
|
||||||
}
|
}
|
||||||
if (x0 <= x1) {
|
if (x0 <= x1) {
|
||||||
pixelwidth = strncmp(im->mode, "I;16", 4) == 0 ? 2 : 1;
|
pixelwidth = strncmp(im->mode, "I;16", 4) == 0 ? 2 : 1;
|
||||||
memset(im->image8[y0] + x0 * pixelwidth, (UINT8) ink,
|
memset(
|
||||||
|
im->image8[y0] + x0 * pixelwidth,
|
||||||
|
(UINT8)ink,
|
||||||
(x1 - x0 + 1) * pixelwidth);
|
(x1 - x0 + 1) * pixelwidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
hline32(Imaging im, int x0, int y0, int x1, int ink)
|
hline32(Imaging im, int x0, int y0, int x1, int ink) {
|
||||||
{
|
|
||||||
int tmp;
|
int tmp;
|
||||||
INT32 *p;
|
INT32 *p;
|
||||||
|
|
||||||
|
@ -154,8 +151,7 @@ hline32(Imaging im, int x0, int y0, int x1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
hline32rgba(Imaging im, int x0, int y0, int x1, int ink)
|
hline32rgba(Imaging im, int x0, int y0, int x1, int ink) {
|
||||||
{
|
|
||||||
int tmp;
|
int tmp;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
|
@ -180,15 +176,15 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink)
|
||||||
out[0] = BLEND(in[3], out[0], in[0], tmp1);
|
out[0] = BLEND(in[3], out[0], in[0], tmp1);
|
||||||
out[1] = BLEND(in[3], out[1], in[1], tmp1);
|
out[1] = BLEND(in[3], out[1], in[1], tmp1);
|
||||||
out[2] = BLEND(in[3], out[2], in[2], tmp1);
|
out[2] = BLEND(in[3], out[2], in[2], tmp1);
|
||||||
x0++; out += 4;
|
x0++;
|
||||||
|
out += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
line8(Imaging im, int x0, int y0, int x1, int y1, int ink) {
|
||||||
{
|
|
||||||
int i, n, e;
|
int i, n, e;
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
|
@ -210,7 +206,6 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
n = (dx > dy) ? dx : dy;
|
n = (dx > dy) ? dx : dy;
|
||||||
|
|
||||||
if (dx == 0) {
|
if (dx == 0) {
|
||||||
|
|
||||||
/* vertical */
|
/* vertical */
|
||||||
for (i = 0; i < dy; i++) {
|
for (i = 0; i < dy; i++) {
|
||||||
point8(im, x0, y0, ink);
|
point8(im, x0, y0, ink);
|
||||||
|
@ -218,7 +213,6 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dy == 0) {
|
} else if (dy == 0) {
|
||||||
|
|
||||||
/* horizontal */
|
/* horizontal */
|
||||||
for (i = 0; i < dx; i++) {
|
for (i = 0; i < dx; i++) {
|
||||||
point8(im, x0, y0, ink);
|
point8(im, x0, y0, ink);
|
||||||
|
@ -226,7 +220,6 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dx > dy) {
|
} else if (dx > dy) {
|
||||||
|
|
||||||
/* bresenham, horizontal slope */
|
/* bresenham, horizontal slope */
|
||||||
n = dx;
|
n = dx;
|
||||||
dy += dy;
|
dy += dy;
|
||||||
|
@ -244,7 +237,6 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* bresenham, vertical slope */
|
/* bresenham, vertical slope */
|
||||||
n = dy;
|
n = dy;
|
||||||
dx += dx;
|
dx += dx;
|
||||||
|
@ -260,13 +252,11 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
e += dx;
|
e += dx;
|
||||||
y0 += ys;
|
y0 += ys;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
line32(Imaging im, int x0, int y0, int x1, int y1, int ink) {
|
||||||
{
|
|
||||||
int i, n, e;
|
int i, n, e;
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
|
@ -288,7 +278,6 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
n = (dx > dy) ? dx : dy;
|
n = (dx > dy) ? dx : dy;
|
||||||
|
|
||||||
if (dx == 0) {
|
if (dx == 0) {
|
||||||
|
|
||||||
/* vertical */
|
/* vertical */
|
||||||
for (i = 0; i < dy; i++) {
|
for (i = 0; i < dy; i++) {
|
||||||
point32(im, x0, y0, ink);
|
point32(im, x0, y0, ink);
|
||||||
|
@ -296,7 +285,6 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dy == 0) {
|
} else if (dy == 0) {
|
||||||
|
|
||||||
/* horizontal */
|
/* horizontal */
|
||||||
for (i = 0; i < dx; i++) {
|
for (i = 0; i < dx; i++) {
|
||||||
point32(im, x0, y0, ink);
|
point32(im, x0, y0, ink);
|
||||||
|
@ -304,7 +292,6 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dx > dy) {
|
} else if (dx > dy) {
|
||||||
|
|
||||||
/* bresenham, horizontal slope */
|
/* bresenham, horizontal slope */
|
||||||
n = dx;
|
n = dx;
|
||||||
dy += dy;
|
dy += dy;
|
||||||
|
@ -322,7 +309,6 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* bresenham, vertical slope */
|
/* bresenham, vertical slope */
|
||||||
n = dy;
|
n = dy;
|
||||||
dx += dx;
|
dx += dx;
|
||||||
|
@ -338,13 +324,11 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
e += dx;
|
e += dx;
|
||||||
y0 += ys;
|
y0 += ys;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) {
|
||||||
{
|
|
||||||
int i, n, e;
|
int i, n, e;
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
|
@ -366,7 +350,6 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
n = (dx > dy) ? dx : dy;
|
n = (dx > dy) ? dx : dy;
|
||||||
|
|
||||||
if (dx == 0) {
|
if (dx == 0) {
|
||||||
|
|
||||||
/* vertical */
|
/* vertical */
|
||||||
for (i = 0; i < dy; i++) {
|
for (i = 0; i < dy; i++) {
|
||||||
point32rgba(im, x0, y0, ink);
|
point32rgba(im, x0, y0, ink);
|
||||||
|
@ -374,7 +357,6 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dy == 0) {
|
} else if (dy == 0) {
|
||||||
|
|
||||||
/* horizontal */
|
/* horizontal */
|
||||||
for (i = 0; i < dx; i++) {
|
for (i = 0; i < dx; i++) {
|
||||||
point32rgba(im, x0, y0, ink);
|
point32rgba(im, x0, y0, ink);
|
||||||
|
@ -382,7 +364,6 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dx > dy) {
|
} else if (dx > dy) {
|
||||||
|
|
||||||
/* bresenham, horizontal slope */
|
/* bresenham, horizontal slope */
|
||||||
n = dx;
|
n = dx;
|
||||||
dy += dy;
|
dy += dy;
|
||||||
|
@ -400,7 +381,6 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* bresenham, vertical slope */
|
/* bresenham, vertical slope */
|
||||||
n = dy;
|
n = dy;
|
||||||
dx += dx;
|
dx += dx;
|
||||||
|
@ -416,13 +396,11 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
|
||||||
e += dx;
|
e += dx;
|
||||||
y0 += ys;
|
y0 += ys;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
x_cmp(const void *x0, const void *x1)
|
x_cmp(const void *x0, const void *x1) {
|
||||||
{
|
|
||||||
float diff = *((float *)x0) - *((float *)x1);
|
float diff = *((float *)x0) - *((float *)x1);
|
||||||
if (diff < 0) {
|
if (diff < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -433,10 +411,9 @@ x_cmp(const void *x0, const void *x1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_horizontal_lines(Imaging im, int n, Edge *e, int ink, int *x_pos, int y, hline_handler hline)
|
draw_horizontal_lines(
|
||||||
{
|
Imaging im, int n, Edge *e, int ink, int *x_pos, int y, hline_handler hline) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (e[i].ymin == y && e[i].ymin == e[i].ymax) {
|
if (e[i].ymin == y && e[i].ymin == e[i].ymax) {
|
||||||
|
@ -467,10 +444,7 @@ draw_horizontal_lines(Imaging im, int n, Edge *e, int ink, int *x_pos, int y, hl
|
||||||
* Filled polygon draw function using scan line algorithm.
|
* Filled polygon draw function using scan line algorithm.
|
||||||
*/
|
*/
|
||||||
static inline int
|
static inline int
|
||||||
polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill,
|
polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, hline_handler hline) {
|
||||||
hline_handler hline)
|
|
||||||
{
|
|
||||||
|
|
||||||
Edge **edge_table;
|
Edge **edge_table;
|
||||||
float *xx;
|
float *xx;
|
||||||
int edge_count = 0;
|
int edge_count = 0;
|
||||||
|
@ -563,26 +537,22 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
polygon8(Imaging im, int n, Edge *e, int ink, int eofill)
|
polygon8(Imaging im, int n, Edge *e, int ink, int eofill) {
|
||||||
{
|
|
||||||
return polygon_generic(im, n, e, ink, eofill, hline8);
|
return polygon_generic(im, n, e, ink, eofill, hline8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
polygon32(Imaging im, int n, Edge *e, int ink, int eofill)
|
polygon32(Imaging im, int n, Edge *e, int ink, int eofill) {
|
||||||
{
|
|
||||||
return polygon_generic(im, n, e, ink, eofill, hline32);
|
return polygon_generic(im, n, e, ink, eofill, hline32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill)
|
polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill) {
|
||||||
{
|
|
||||||
return polygon_generic(im, n, e, ink, eofill, hline32rgba);
|
return polygon_generic(im, n, e, ink, eofill, hline32rgba);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
add_edge(Edge *e, int x0, int y0, int x1, int y1)
|
add_edge(Edge *e, int x0, int y0, int x1, int y1) {
|
||||||
{
|
|
||||||
/* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */
|
/* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */
|
||||||
|
|
||||||
if (x0 <= x1) {
|
if (x0 <= x1) {
|
||||||
|
@ -638,8 +608,7 @@ DRAW draw32rgba = { point32rgba, hline32rgba, line32rgba, polygon32rgba };
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawPoint(Imaging im, int x0, int y0, const void* ink_, int op)
|
ImagingDrawPoint(Imaging im, int x0, int y0, const void *ink_, int op) {
|
||||||
{
|
|
||||||
DRAW *draw;
|
DRAW *draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
|
|
||||||
|
@ -651,9 +620,7 @@ ImagingDrawPoint(Imaging im, int x0, int y0, const void* ink_, int op)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void* ink_,
|
ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void *ink_, int op) {
|
||||||
int op)
|
|
||||||
{
|
|
||||||
DRAW *draw;
|
DRAW *draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
|
|
||||||
|
@ -665,9 +632,8 @@ ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void* ink_,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
|
ImagingDrawWideLine(
|
||||||
const void* ink_, int width, int op)
|
Imaging im, int x0, int y0, int x1, int y1, const void *ink_, int width, int op) {
|
||||||
{
|
|
||||||
DRAW *draw;
|
DRAW *draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
|
@ -698,8 +664,7 @@ ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
{x0 - dxmin, y0 + dymax},
|
{x0 - dxmin, y0 + dymax},
|
||||||
{x1 - dxmin, y1 + dymax},
|
{x1 - dxmin, y1 + dymax},
|
||||||
{x1 + dxmax, y1 - dymin},
|
{x1 + dxmax, y1 - dymin},
|
||||||
{x0 + dxmax, y0 - dymin}
|
{x0 + dxmax, y0 - dymin}};
|
||||||
};
|
|
||||||
|
|
||||||
add_edge(e + 0, vertices[0][0], vertices[0][1], vertices[1][0], vertices[1][1]);
|
add_edge(e + 0, vertices[0][0], vertices[0][1], vertices[1][0], vertices[1][1]);
|
||||||
add_edge(e + 1, vertices[1][0], vertices[1][1], vertices[2][0], vertices[2][1]);
|
add_edge(e + 1, vertices[1][0], vertices[1][1], vertices[2][0], vertices[2][1]);
|
||||||
|
@ -712,9 +677,16 @@ ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
|
ImagingDrawRectangle(
|
||||||
const void* ink_, int fill, int width, int op)
|
Imaging im,
|
||||||
{
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
const void *ink_,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
int i;
|
int i;
|
||||||
int y;
|
int y;
|
||||||
int tmp;
|
int tmp;
|
||||||
|
@ -728,7 +700,6 @@ ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fill) {
|
if (fill) {
|
||||||
|
|
||||||
if (y0 < 0) {
|
if (y0 < 0) {
|
||||||
y0 = 0;
|
y0 = 0;
|
||||||
} else if (y0 >= im->ysize) {
|
} else if (y0 >= im->ysize) {
|
||||||
|
@ -762,9 +733,7 @@ ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_,
|
ImagingDrawPolygon(Imaging im, int count, int *xy, const void *ink_, int fill, int op) {
|
||||||
int fill, int op)
|
|
||||||
{
|
|
||||||
int i, n;
|
int i, n;
|
||||||
DRAW *draw;
|
DRAW *draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
|
@ -776,7 +745,6 @@ ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_,
|
||||||
DRAWINIT();
|
DRAWINIT();
|
||||||
|
|
||||||
if (fill) {
|
if (fill) {
|
||||||
|
|
||||||
/* Build edge list */
|
/* Build edge list */
|
||||||
/* malloc check ok, using calloc */
|
/* malloc check ok, using calloc */
|
||||||
Edge *e = calloc(count, sizeof(Edge));
|
Edge *e = calloc(count, sizeof(Edge));
|
||||||
|
@ -794,26 +762,20 @@ ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_,
|
||||||
free(e);
|
free(e);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Outline */
|
/* Outline */
|
||||||
for (i = 0; i < count - 1; i++) {
|
for (i = 0; i < count - 1; i++) {
|
||||||
draw->line(im, xy[i + i], xy[i + i + 1], xy[i + i + 2], xy[i + i + 3], ink);
|
draw->line(im, xy[i + i], xy[i + i + 1], xy[i + i + 2], xy[i + i + 3], ink);
|
||||||
}
|
}
|
||||||
draw->line(im, xy[i + i], xy[i + i + 1], xy[0], xy[1], ink);
|
draw->line(im, xy[i + i], xy[i + i + 1], xy[0], xy[1], ink);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void* ink,
|
ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void *ink, int op) {
|
||||||
int op)
|
|
||||||
{
|
|
||||||
return ImagingFill2(
|
return ImagingFill2(
|
||||||
im, ink, bitmap,
|
im, ink, bitmap, x0, y0, x0 + bitmap->xsize, y0 + bitmap->ysize);
|
||||||
x0, y0, x0 + bitmap->xsize, y0 + bitmap->ysize
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -830,7 +792,8 @@ typedef struct {
|
||||||
int8_t finished;
|
int8_t finished;
|
||||||
} quarter_state;
|
} quarter_state;
|
||||||
|
|
||||||
void quarter_init(quarter_state* s, int32_t a, int32_t b) {
|
void
|
||||||
|
quarter_init(quarter_state *s, int32_t a, int32_t b) {
|
||||||
if (a < 0 || b < 0) {
|
if (a < 0 || b < 0) {
|
||||||
s->finished = 1;
|
s->finished = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -849,11 +812,13 @@ void quarter_init(quarter_state* s, int32_t a, int32_t b) {
|
||||||
|
|
||||||
// deviation of the point from ellipse curve, basically a substitution
|
// deviation of the point from ellipse curve, basically a substitution
|
||||||
// of the point into the ellipse equation
|
// of the point into the ellipse equation
|
||||||
int64_t quarter_delta(quarter_state* s, int64_t x, int64_t y) {
|
int64_t
|
||||||
|
quarter_delta(quarter_state *s, int64_t x, int64_t y) {
|
||||||
return llabs(s->a2 * y * y + s->b2 * x * x - s->a2b2);
|
return llabs(s->a2 * y * y + s->b2 * x * x - s->a2b2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t quarter_next(quarter_state* s, int32_t* ret_x, int32_t* ret_y) {
|
int8_t
|
||||||
|
quarter_next(quarter_state *s, int32_t *ret_x, int32_t *ret_y) {
|
||||||
if (s->finished) {
|
if (s->finished) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -903,7 +868,8 @@ typedef struct {
|
||||||
int8_t leftmost;
|
int8_t leftmost;
|
||||||
} ellipse_state;
|
} ellipse_state;
|
||||||
|
|
||||||
void ellipse_init(ellipse_state* s, int32_t a, int32_t b, int32_t w) {
|
void
|
||||||
|
ellipse_init(ellipse_state *s, int32_t a, int32_t b, int32_t w) {
|
||||||
s->bufcnt = 0;
|
s->bufcnt = 0;
|
||||||
s->leftmost = a % 2;
|
s->leftmost = a % 2;
|
||||||
quarter_init(&s->st_o, a, b);
|
quarter_init(&s->st_o, a, b);
|
||||||
|
@ -916,7 +882,8 @@ void ellipse_init(ellipse_state* s, int32_t a, int32_t b, int32_t w) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t ellipse_next(ellipse_state* s, int32_t* ret_x0, int32_t* ret_y, int32_t* ret_x1) {
|
int8_t
|
||||||
|
ellipse_next(ellipse_state *s, int32_t *ret_x0, int32_t *ret_y, int32_t *ret_x1) {
|
||||||
if (s->bufcnt == 0) {
|
if (s->bufcnt == 0) {
|
||||||
if (s->finished) {
|
if (s->finished) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -998,7 +965,8 @@ typedef struct event_list {
|
||||||
} event_list;
|
} event_list;
|
||||||
|
|
||||||
// Mirrors all the clipping nodes of the tree relative to the y = x line.
|
// Mirrors all the clipping nodes of the tree relative to the y = x line.
|
||||||
void clip_tree_transpose(clip_node* root) {
|
void
|
||||||
|
clip_tree_transpose(clip_node *root) {
|
||||||
if (root != NULL) {
|
if (root != NULL) {
|
||||||
if (root->type == CT_CLIP) {
|
if (root->type == CT_CLIP) {
|
||||||
double t = root->a;
|
double t = root->a;
|
||||||
|
@ -1014,7 +982,9 @@ void clip_tree_transpose(clip_node* root) {
|
||||||
// non-intersecting segments sorted by X coordinate.
|
// non-intersecting segments sorted by X coordinate.
|
||||||
// Combining nodes (AND, OR) may also accept sequences for intersecting
|
// Combining nodes (AND, OR) may also accept sequences for intersecting
|
||||||
// segments, i.e. something like correct bracket sequences.
|
// segments, i.e. something like correct bracket sequences.
|
||||||
int clip_tree_do_clip(clip_node* root, int32_t x0, int32_t y, int32_t x1, event_list** ret) {
|
int
|
||||||
|
clip_tree_do_clip(
|
||||||
|
clip_node *root, int32_t x0, int32_t y, int32_t x1, event_list **ret) {
|
||||||
if (root == NULL) {
|
if (root == NULL) {
|
||||||
event_list *start = malloc(sizeof(event_list));
|
event_list *start = malloc(sizeof(event_list));
|
||||||
if (!start) {
|
if (!start) {
|
||||||
|
@ -1100,7 +1070,9 @@ int clip_tree_do_clip(clip_node* root, int32_t x0, int32_t y, int32_t x1, event_
|
||||||
int32_t k2 = 0;
|
int32_t k2 = 0;
|
||||||
while (l1 != NULL || l2 != NULL) {
|
while (l1 != NULL || l2 != NULL) {
|
||||||
event_list *t;
|
event_list *t;
|
||||||
if (l2 == NULL || (l1 != NULL && (l1->x < l2->x || (l1->x == l2->x && l1->type > l2->type)))) {
|
if (l2 == NULL ||
|
||||||
|
(l1 != NULL &&
|
||||||
|
(l1->x < l2->x || (l1->x == l2->x && l1->type > l2->type)))) {
|
||||||
t = l1;
|
t = l1;
|
||||||
k1 += t->type;
|
k1 += t->type;
|
||||||
assert(k1 >= 0);
|
assert(k1 >= 0);
|
||||||
|
@ -1112,14 +1084,14 @@ int clip_tree_do_clip(clip_node* root, int32_t x0, int32_t y, int32_t x1, event_
|
||||||
l2 = l2->next;
|
l2 = l2->next;
|
||||||
}
|
}
|
||||||
t->next = NULL;
|
t->next = NULL;
|
||||||
if ((root->type == CT_OR && (
|
if ((root->type == CT_OR &&
|
||||||
(t->type == 1 && (tail == NULL || tail->type == -1)) ||
|
((t->type == 1 && (tail == NULL || tail->type == -1)) ||
|
||||||
(t->type == -1 && k1 == 0 && k2 == 0)
|
(t->type == -1 && k1 == 0 && k2 == 0))) ||
|
||||||
)) ||
|
(root->type == CT_AND &&
|
||||||
(root->type == CT_AND && (
|
((t->type == 1 && (tail == NULL || tail->type == -1) && k1 > 0 &&
|
||||||
(t->type == 1 && (tail == NULL || tail->type == -1) && k1 > 0 && k2 > 0) ||
|
k2 > 0) ||
|
||||||
(t->type == -1 && tail != NULL && tail->type == 1 && (k1 == 0 || k2 == 0))
|
(t->type == -1 && tail != NULL && tail->type == 1 &&
|
||||||
))) {
|
(k1 == 0 || k2 == 0))))) {
|
||||||
if (tail == NULL) {
|
if (tail == NULL) {
|
||||||
*ret = t;
|
*ret = t;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1148,9 +1120,11 @@ typedef struct {
|
||||||
int32_t y;
|
int32_t y;
|
||||||
} clip_ellipse_state;
|
} clip_ellipse_state;
|
||||||
|
|
||||||
typedef void (*clip_ellipse_init)(clip_ellipse_state*, int32_t, int32_t, int32_t, float, float);
|
typedef void (*clip_ellipse_init)(
|
||||||
|
clip_ellipse_state *, int32_t, int32_t, int32_t, float, float);
|
||||||
|
|
||||||
void debug_clip_tree(clip_node* root, int space) {
|
void
|
||||||
|
debug_clip_tree(clip_node *root, int space) {
|
||||||
if (root == NULL) {
|
if (root == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1175,7 +1149,8 @@ void debug_clip_tree(clip_node* root, int space) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resulting angles will satisfy 0 <= al < 360, al <= ar <= al + 360
|
// Resulting angles will satisfy 0 <= al < 360, al <= ar <= al + 360
|
||||||
void normalize_angles(float* al, float* ar) {
|
void
|
||||||
|
normalize_angles(float *al, float *ar) {
|
||||||
if (*ar - *al >= 360) {
|
if (*ar - *al >= 360) {
|
||||||
*al = 0;
|
*al = 0;
|
||||||
*ar = 360;
|
*ar = 360;
|
||||||
|
@ -1186,7 +1161,8 @@ void normalize_angles(float* al, float* ar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// An arc with caps orthogonal to the ellipse curve.
|
// An arc with caps orthogonal to the ellipse curve.
|
||||||
void arc_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float ar) {
|
void
|
||||||
|
arc_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) {
|
||||||
if (a < b) {
|
if (a < b) {
|
||||||
// transpose the coordinate system
|
// transpose the coordinate system
|
||||||
arc_init(s, b, a, w, 90 - ar, 90 - al);
|
arc_init(s, b, a, w, 90 - ar, 90 - al);
|
||||||
|
@ -1255,7 +1231,9 @@ void arc_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al,
|
||||||
}
|
}
|
||||||
|
|
||||||
// A chord line.
|
// A chord line.
|
||||||
void chord_line_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float ar) {
|
void
|
||||||
|
chord_line_init(
|
||||||
|
clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) {
|
||||||
ellipse_init(&s->st, a, b, a + b + 1);
|
ellipse_init(&s->st, a, b, a + b + 1);
|
||||||
|
|
||||||
s->head = NULL;
|
s->head = NULL;
|
||||||
|
@ -1275,11 +1253,14 @@ void chord_line_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, flo
|
||||||
s->root->l->c = -(s->root->l->a * xl + s->root->l->b * yl);
|
s->root->l->c = -(s->root->l->a * xl + s->root->l->b * yl);
|
||||||
s->root->r->a = -s->root->l->a;
|
s->root->r->a = -s->root->l->a;
|
||||||
s->root->r->b = -s->root->l->b;
|
s->root->r->b = -s->root->l->b;
|
||||||
s->root->r->c = 2 * w * sqrt(pow(s->root->l->a, 2.0) + pow(s->root->l->b, 2.0)) - s->root->l->c;
|
s->root->r->c =
|
||||||
|
2 * w * sqrt(pow(s->root->l->a, 2.0) + pow(s->root->l->b, 2.0)) - s->root->l->c;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pie side.
|
// Pie side.
|
||||||
void pie_side_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float _) {
|
void
|
||||||
|
pie_side_init(
|
||||||
|
clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float _) {
|
||||||
ellipse_init(&s->st, a, b, a + b + 1);
|
ellipse_init(&s->st, a, b, a + b + 1);
|
||||||
|
|
||||||
s->head = NULL;
|
s->head = NULL;
|
||||||
|
@ -1321,7 +1302,8 @@ void pie_side_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float
|
||||||
}
|
}
|
||||||
|
|
||||||
// A chord.
|
// A chord.
|
||||||
void chord_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float ar) {
|
void
|
||||||
|
chord_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) {
|
||||||
ellipse_init(&s->st, a, b, w);
|
ellipse_init(&s->st, a, b, w);
|
||||||
|
|
||||||
s->head = NULL;
|
s->head = NULL;
|
||||||
|
@ -1339,7 +1321,8 @@ void chord_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al
|
||||||
}
|
}
|
||||||
|
|
||||||
// A pie. Can also be used to draw an arc with ugly sharp caps.
|
// A pie. Can also be used to draw an arc with ugly sharp caps.
|
||||||
void pie_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al, float ar) {
|
void
|
||||||
|
pie_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) {
|
||||||
ellipse_init(&s->st, a, b, w);
|
ellipse_init(&s->st, a, b, w);
|
||||||
|
|
||||||
s->head = NULL;
|
s->head = NULL;
|
||||||
|
@ -1366,7 +1349,8 @@ void pie_init(clip_ellipse_state* s, int32_t a, int32_t b, int32_t w, float al,
|
||||||
s->root->type = ar - al < 180 ? CT_AND : CT_OR;
|
s->root->type = ar - al < 180 ? CT_AND : CT_OR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clip_ellipse_free(clip_ellipse_state* s) {
|
void
|
||||||
|
clip_ellipse_free(clip_ellipse_state *s) {
|
||||||
while (s->head != NULL) {
|
while (s->head != NULL) {
|
||||||
event_list *t = s->head;
|
event_list *t = s->head;
|
||||||
s->head = s->head->next;
|
s->head = s->head->next;
|
||||||
|
@ -1374,7 +1358,9 @@ void clip_ellipse_free(clip_ellipse_state* s) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t clip_ellipse_next(clip_ellipse_state* s, int32_t* ret_x0, int32_t* ret_y, int32_t* ret_x1) {
|
int8_t
|
||||||
|
clip_ellipse_next(
|
||||||
|
clip_ellipse_state *s, int32_t *ret_x0, int32_t *ret_y, int32_t *ret_x1) {
|
||||||
int32_t x0, y, x1;
|
int32_t x0, y, x1;
|
||||||
while (s->head == NULL && ellipse_next(&s->st, &x0, &y, &x1) >= 0) {
|
while (s->head == NULL && ellipse_next(&s->st, &x0, &y, &x1) >= 0) {
|
||||||
if (clip_tree_do_clip(s->root, x0, y, x1, &s->head) < 0) {
|
if (clip_tree_do_clip(s->root, x0, y, x1, &s->head) < 0) {
|
||||||
|
@ -1399,10 +1385,16 @@ int8_t clip_ellipse_next(clip_ellipse_state* s, int32_t* ret_x0, int32_t* ret_y,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ellipseNew(Imaging im, int x0, int y0, int x1, int y1,
|
ellipseNew(
|
||||||
const void* ink_, int fill,
|
Imaging im,
|
||||||
int width, int op)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
const void *ink_,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
DRAW *draw;
|
DRAW *draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
DRAWINIT();
|
DRAWINIT();
|
||||||
|
@ -1426,10 +1418,18 @@ ellipseNew(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
clipEllipseNew(Imaging im, int x0, int y0, int x1, int y1,
|
clipEllipseNew(
|
||||||
float start, float end,
|
Imaging im,
|
||||||
const void* ink_, int width, int op, clip_ellipse_init init)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink_,
|
||||||
|
int width,
|
||||||
|
int op,
|
||||||
|
clip_ellipse_init init) {
|
||||||
DRAW *draw;
|
DRAW *draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
DRAWINIT();
|
DRAWINIT();
|
||||||
|
@ -1452,56 +1452,106 @@ clipEllipseNew(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
return next_code == -1 ? 0 : -1;
|
return next_code == -1 ? 0 : -1;
|
||||||
}
|
}
|
||||||
static int
|
static int
|
||||||
arcNew(Imaging im, int x0, int y0, int x1, int y1,
|
arcNew(
|
||||||
float start, float end,
|
Imaging im,
|
||||||
const void* ink_, int width, int op)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink_,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, arc_init);
|
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, arc_init);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
chordNew(Imaging im, int x0, int y0, int x1, int y1,
|
chordNew(
|
||||||
float start, float end,
|
Imaging im,
|
||||||
const void* ink_, int width, int op)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink_,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, chord_init);
|
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, chord_init);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
chordLineNew(Imaging im, int x0, int y0, int x1, int y1,
|
chordLineNew(
|
||||||
float start, float end,
|
Imaging im,
|
||||||
const void* ink_, int width, int op)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, chord_line_init);
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink_,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
|
return clipEllipseNew(
|
||||||
|
im, x0, y0, x1, y1, start, end, ink_, width, op, chord_line_init);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pieNew(Imaging im, int x0, int y0, int x1, int y1,
|
pieNew(
|
||||||
float start, float end,
|
Imaging im,
|
||||||
const void* ink_, int width, int op)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink_,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, pie_init);
|
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, pie_init);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pieSideNew(Imaging im, int x0, int y0, int x1, int y1,
|
pieSideNew(
|
||||||
|
Imaging im,
|
||||||
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
float start,
|
float start,
|
||||||
const void* ink_, int width, int op)
|
const void *ink_,
|
||||||
{
|
int width,
|
||||||
|
int op) {
|
||||||
return clipEllipseNew(im, x0, y0, x1, y1, start, 0, ink_, width, op, pie_side_init);
|
return clipEllipseNew(im, x0, y0, x1, y1, start, 0, ink_, width, op, pie_side_init);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1,
|
ImagingDrawEllipse(
|
||||||
const void* ink, int fill, int width, int op)
|
Imaging im,
|
||||||
{
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
const void *ink,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
|
return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1,
|
ImagingDrawArc(
|
||||||
float start, float end, const void* ink, int width, int op)
|
Imaging im,
|
||||||
{
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
normalize_angles(&start, &end);
|
normalize_angles(&start, &end);
|
||||||
if (start + 360 == end) {
|
if (start + 360 == end) {
|
||||||
return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, 0, width, op);
|
return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, 0, width, op);
|
||||||
|
@ -1512,12 +1562,19 @@ ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
return arcNew(im, x0, y0, x1, y1, start, end, ink, width, op);
|
return arcNew(im, x0, y0, x1, y1, start, end, ink, width, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1,
|
ImagingDrawChord(
|
||||||
float start, float end, const void* ink, int fill,
|
Imaging im,
|
||||||
int width, int op)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
normalize_angles(&start, &end);
|
normalize_angles(&start, &end);
|
||||||
if (start + 360 == end) {
|
if (start + 360 == end) {
|
||||||
return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, fill, width, op);
|
return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, fill, width, op);
|
||||||
|
@ -1535,12 +1592,19 @@ ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1,
|
ImagingDrawPieslice(
|
||||||
float start, float end, const void* ink, int fill,
|
Imaging im,
|
||||||
int width, int op)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
|
int op) {
|
||||||
normalize_angles(&start, &end);
|
normalize_angles(&start, &end);
|
||||||
if (start + 360 == end) {
|
if (start + 360 == end) {
|
||||||
return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
|
return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
|
||||||
|
@ -1563,7 +1627,6 @@ ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* experimental level 2 ("arrow") graphics stuff. this implements
|
/* experimental level 2 ("arrow") graphics stuff. this implements
|
||||||
|
@ -1572,7 +1635,6 @@ ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
itself */
|
itself */
|
||||||
|
|
||||||
struct ImagingOutlineInstance {
|
struct ImagingOutlineInstance {
|
||||||
|
|
||||||
float x0, y0;
|
float x0, y0;
|
||||||
|
|
||||||
float x, y;
|
float x, y;
|
||||||
|
@ -1581,13 +1643,10 @@ struct ImagingOutlineInstance {
|
||||||
Edge *edges;
|
Edge *edges;
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ImagingOutline
|
ImagingOutline
|
||||||
ImagingOutlineNew(void)
|
ImagingOutlineNew(void) {
|
||||||
{
|
|
||||||
ImagingOutline outline;
|
ImagingOutline outline;
|
||||||
|
|
||||||
outline = calloc(1, sizeof(struct ImagingOutlineInstance));
|
outline = calloc(1, sizeof(struct ImagingOutlineInstance));
|
||||||
|
@ -1604,8 +1663,7 @@ ImagingOutlineNew(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingOutlineDelete(ImagingOutline outline)
|
ImagingOutlineDelete(ImagingOutline outline) {
|
||||||
{
|
|
||||||
if (!outline) {
|
if (!outline) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1617,10 +1675,8 @@ ImagingOutlineDelete(ImagingOutline outline)
|
||||||
free(outline);
|
free(outline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Edge *
|
static Edge *
|
||||||
allocate(ImagingOutline outline, int extra)
|
allocate(ImagingOutline outline, int extra) {
|
||||||
{
|
|
||||||
Edge *e;
|
Edge *e;
|
||||||
|
|
||||||
if (outline->count + extra > outline->size) {
|
if (outline->count + extra > outline->size) {
|
||||||
|
@ -1650,8 +1706,7 @@ allocate(ImagingOutline outline, int extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingOutlineMove(ImagingOutline outline, float x0, float y0)
|
ImagingOutlineMove(ImagingOutline outline, float x0, float y0) {
|
||||||
{
|
|
||||||
outline->x = outline->x0 = x0;
|
outline->x = outline->x0 = x0;
|
||||||
outline->y = outline->y0 = y0;
|
outline->y = outline->y0 = y0;
|
||||||
|
|
||||||
|
@ -1659,8 +1714,7 @@ ImagingOutlineMove(ImagingOutline outline, float x0, float y0)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingOutlineLine(ImagingOutline outline, float x1, float y1)
|
ImagingOutlineLine(ImagingOutline outline, float x1, float y1) {
|
||||||
{
|
|
||||||
Edge *e;
|
Edge *e;
|
||||||
|
|
||||||
e = allocate(outline, 1);
|
e = allocate(outline, 1);
|
||||||
|
@ -1677,9 +1731,14 @@ ImagingOutlineLine(ImagingOutline outline, float x1, float y1)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
|
ImagingOutlineCurve(
|
||||||
float x2, float y2, float x3, float y3)
|
ImagingOutline outline,
|
||||||
{
|
float x1,
|
||||||
|
float y1,
|
||||||
|
float x2,
|
||||||
|
float y2,
|
||||||
|
float x3,
|
||||||
|
float y3) {
|
||||||
Edge *e;
|
Edge *e;
|
||||||
int i;
|
int i;
|
||||||
float xo, yo;
|
float xo, yo;
|
||||||
|
@ -1697,7 +1756,6 @@ ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
|
||||||
/* flatten the bezier segment */
|
/* flatten the bezier segment */
|
||||||
|
|
||||||
for (i = 1; i <= STEPS; i++) {
|
for (i = 1; i <= STEPS; i++) {
|
||||||
|
|
||||||
float t = ((float)i) / STEPS;
|
float t = ((float)i) / STEPS;
|
||||||
float t2 = t * t;
|
float t2 = t * t;
|
||||||
float t3 = t2 * t;
|
float t3 = t2 * t;
|
||||||
|
@ -1712,7 +1770,6 @@ ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
|
||||||
add_edge(e++, xo, yo, (int)x, (int)y);
|
add_edge(e++, xo, yo, (int)x, (int)y);
|
||||||
|
|
||||||
xo = x, yo = y;
|
xo = x, yo = y;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outline->x = xo;
|
outline->x = xo;
|
||||||
|
@ -1722,8 +1779,7 @@ ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingOutlineClose(ImagingOutline outline)
|
ImagingOutlineClose(ImagingOutline outline) {
|
||||||
{
|
|
||||||
if (outline->x == outline->x0 && outline->y == outline->y0) {
|
if (outline->x == outline->x0 && outline->y == outline->y0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1731,16 +1787,19 @@ ImagingOutlineClose(ImagingOutline outline)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingOutlineTransform(ImagingOutline outline, double a[6])
|
ImagingOutlineTransform(ImagingOutline outline, double a[6]) {
|
||||||
{
|
|
||||||
Edge *eIn;
|
Edge *eIn;
|
||||||
Edge *eOut;
|
Edge *eOut;
|
||||||
int i, n;
|
int i, n;
|
||||||
int x0, y0, x1, y1;
|
int x0, y0, x1, y1;
|
||||||
int X0, Y0, X1, Y1;
|
int X0, Y0, X1, Y1;
|
||||||
|
|
||||||
double a0 = a[0]; double a1 = a[1]; double a2 = a[2];
|
double a0 = a[0];
|
||||||
double a3 = a[3]; double a4 = a[4]; double a5 = a[5];
|
double a1 = a[1];
|
||||||
|
double a2 = a[2];
|
||||||
|
double a3 = a[3];
|
||||||
|
double a4 = a[4];
|
||||||
|
double a5 = a[5];
|
||||||
|
|
||||||
eIn = outline->edges;
|
eIn = outline->edges;
|
||||||
n = outline->count;
|
n = outline->count;
|
||||||
|
@ -1758,7 +1817,6 @@ ImagingOutlineTransform(ImagingOutline outline, double a[6])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|
||||||
x0 = eIn->x0;
|
x0 = eIn->x0;
|
||||||
y0 = eIn->y0;
|
y0 = eIn->y0;
|
||||||
|
|
||||||
|
@ -1787,7 +1845,6 @@ ImagingOutlineTransform(ImagingOutline outline, double a[6])
|
||||||
|
|
||||||
eIn++;
|
eIn++;
|
||||||
eOut++;
|
eOut++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(eIn);
|
free(eIn);
|
||||||
|
@ -1796,9 +1853,8 @@ ImagingOutlineTransform(ImagingOutline outline, double a[6])
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingDrawOutline(Imaging im, ImagingOutline outline, const void* ink_,
|
ImagingDrawOutline(
|
||||||
int fill, int op)
|
Imaging im, ImagingOutline outline, const void *ink_, int fill, int op) {
|
||||||
{
|
|
||||||
DRAW *draw;
|
DRAW *draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,12 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality)
|
ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality) {
|
||||||
{
|
|
||||||
/* Generate a Mandelbrot set covering the given extent */
|
/* Generate a Mandelbrot set covering the given extent */
|
||||||
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
@ -74,8 +72,7 @@ ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingEffectNoise(int xsize, int ysize, float sigma)
|
ImagingEffectNoise(int xsize, int ysize, float sigma) {
|
||||||
{
|
|
||||||
/* Generate Gaussian noise centered around 128 */
|
/* Generate Gaussian noise centered around 128 */
|
||||||
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
|
@ -117,8 +114,7 @@ ImagingEffectNoise(int xsize, int ysize, float sigma)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingEffectSpread(Imaging imIn, int distance)
|
ImagingEffectSpread(Imaging imIn, int distance) {
|
||||||
{
|
|
||||||
/* Randomly spread pixels in an image */
|
/* Randomly spread pixels in an image */
|
||||||
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
|
|
|
@ -17,13 +17,10 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
enum { HEXBYTE = 1, NEWLINE };
|
enum { HEXBYTE = 1, NEWLINE };
|
||||||
const char *hex = "0123456789abcdef";
|
const char *hex = "0123456789abcdef";
|
||||||
|
|
||||||
|
@ -38,7 +35,6 @@ ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
in = (UINT8 *)im->image[state->y];
|
in = (UINT8 *)im->image[state->y];
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (state->state == NEWLINE) {
|
if (state->state == NEWLINE) {
|
||||||
if (bytes < 1) {
|
if (bytes < 1) {
|
||||||
break;
|
break;
|
||||||
|
@ -75,9 +71,7 @@ ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
in = (UINT8 *)im->image[state->y];
|
in = (UINT8 *)im->image[state->y];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,41 +19,34 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
/* exception state */
|
/* exception state */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ImagingError_OSError(void)
|
ImagingError_OSError(void) {
|
||||||
{
|
|
||||||
fprintf(stderr, "*** exception: file access error\n");
|
fprintf(stderr, "*** exception: file access error\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ImagingError_MemoryError(void)
|
ImagingError_MemoryError(void) {
|
||||||
{
|
|
||||||
fprintf(stderr, "*** exception: out of memory\n");
|
fprintf(stderr, "*** exception: out of memory\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ImagingError_ModeError(void)
|
ImagingError_ModeError(void) {
|
||||||
{
|
|
||||||
return ImagingError_ValueError("bad image mode");
|
return ImagingError_ValueError("bad image mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ImagingError_Mismatch(void)
|
ImagingError_Mismatch(void) {
|
||||||
{
|
|
||||||
return ImagingError_ValueError("images don't match");
|
return ImagingError_ValueError("images don't match");
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ImagingError_ValueError(const char *message)
|
ImagingError_ValueError(const char *message) {
|
||||||
{
|
|
||||||
if (!message) {
|
if (!message) {
|
||||||
message = "exception: bad argument to function";
|
message = "exception: bad argument to function";
|
||||||
}
|
}
|
||||||
|
@ -62,21 +55,18 @@ ImagingError_ValueError(const char *message)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingError_Clear(void)
|
ImagingError_Clear(void) {
|
||||||
{
|
|
||||||
/* nop */;
|
/* nop */;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* thread state */
|
/* thread state */
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingSectionEnter(ImagingSectionCookie* cookie)
|
ImagingSectionEnter(ImagingSectionCookie *cookie) {
|
||||||
{
|
|
||||||
/* pass */
|
/* pass */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingSectionLeave(ImagingSectionCookie* cookie)
|
ImagingSectionLeave(ImagingSectionCookie *cookie) {
|
||||||
{
|
|
||||||
/* pass */
|
/* pass */
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,19 +15,15 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingSaveRaw(Imaging im, FILE* fp)
|
ImagingSaveRaw(Imaging im, FILE *fp) {
|
||||||
{
|
|
||||||
int x, y, i;
|
int x, y, i;
|
||||||
|
|
||||||
if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) {
|
if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) {
|
||||||
|
|
||||||
/* @PIL227: FIXME: for mode "1", map != 0 to 255 */
|
/* @PIL227: FIXME: for mode "1", map != 0 to 255 */
|
||||||
|
|
||||||
/* PGM "L" */
|
/* PGM "L" */
|
||||||
|
@ -36,23 +32,19 @@ ImagingSaveRaw(Imaging im, FILE* fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* PPM "RGB" or other internal format */
|
/* PPM "RGB" or other internal format */
|
||||||
for (y = 0; y < im->ysize; y++) {
|
for (y = 0; y < im->ysize; y++) {
|
||||||
for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) {
|
for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) {
|
||||||
fwrite(im->image[y] + i, 1, im->bands, fp);
|
fwrite(im->image[y] + i, 1, im->bands, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingSavePPM(Imaging im, const char* outfile)
|
ImagingSavePPM(Imaging im, const char *outfile) {
|
||||||
{
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if (!im) {
|
if (!im) {
|
||||||
|
@ -84,4 +76,3 @@ ImagingSavePPM(Imaging im, const char* outfile)
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,12 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingFill(Imaging im, const void* colour)
|
ImagingFill(Imaging im, const void *colour) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
|
|
||||||
|
@ -65,8 +63,7 @@ ImagingFill(Imaging im, const void* colour)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingFillLinearGradient(const char *mode)
|
ImagingFillLinearGradient(const char *mode) {
|
||||||
{
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
|
@ -87,8 +84,7 @@ ImagingFillLinearGradient(const char *mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingFillRadialGradient(const char *mode)
|
ImagingFillRadialGradient(const char *mode) {
|
||||||
{
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
int x, y;
|
int x, y;
|
||||||
int d;
|
int d;
|
||||||
|
@ -104,7 +100,8 @@ ImagingFillRadialGradient(const char *mode)
|
||||||
|
|
||||||
for (y = 0; y < 256; y++) {
|
for (y = 0; y < 256; y++) {
|
||||||
for (x = 0; x < 256; x++) {
|
for (x = 0; x < 256; x++) {
|
||||||
d = (int) sqrt((double) ((x-128)*(x-128) + (y-128)*(y-128)) * 2.0);
|
d = (int)sqrt(
|
||||||
|
(double)((x - 128) * (x - 128) + (y - 128) * (y - 128)) * 2.0);
|
||||||
if (d >= 255) {
|
if (d >= 255) {
|
||||||
im->image8[y][x] = 255;
|
im->image8[y][x] = 255;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
static inline UINT8
|
||||||
static inline UINT8 clip8(float in)
|
clip8(float in) {
|
||||||
{
|
|
||||||
if (in <= 0.0) {
|
if (in <= 0.0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -39,8 +38,7 @@ static inline UINT8 clip8(float in)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode)
|
ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode) {
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int x, y;
|
int x, y;
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
|
@ -55,7 +53,8 @@ ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EXPAND_LINE(type, image, yin, yout) {\
|
#define EXPAND_LINE(type, image, yin, yout) \
|
||||||
|
{ \
|
||||||
for (x = 0; x < xmargin; x++) { \
|
for (x = 0; x < xmargin; x++) { \
|
||||||
imOut->image[yout][x] = imIn->image[yin][0]; \
|
imOut->image[yout][x] = imIn->image[yin][0]; \
|
||||||
} \
|
} \
|
||||||
|
@ -68,7 +67,8 @@ ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode)
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EXPAND(type, image) {\
|
#define EXPAND(type, image) \
|
||||||
|
{ \
|
||||||
for (y = 0; y < ymargin; y++) { \
|
for (y = 0; y < ymargin; y++) { \
|
||||||
EXPAND_LINE(type, image, 0, y); \
|
EXPAND_LINE(type, image, 0, y); \
|
||||||
} \
|
} \
|
||||||
|
@ -93,14 +93,10 @@ ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel,
|
ImagingFilter3x3(Imaging imOut, Imaging im, const float *kernel, float offset) {
|
||||||
float offset)
|
#define KERNEL1x3(in0, x, kernel, d) \
|
||||||
{
|
(_i2f((UINT8)in0[x - d]) * (kernel)[0] + _i2f((UINT8)in0[x]) * (kernel)[1] + \
|
||||||
#define KERNEL1x3(in0, x, kernel, d) ( \
|
|
||||||
_i2f((UINT8) in0[x-d]) * (kernel)[0] + \
|
|
||||||
_i2f((UINT8) in0[x]) * (kernel)[1] + \
|
|
||||||
_i2f((UINT8)in0[x + d]) * (kernel)[2])
|
_i2f((UINT8)in0[x + d]) * (kernel)[2])
|
||||||
|
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
|
@ -164,8 +160,7 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel,
|
||||||
ss0 += KERNEL1x3(in_1, x * 4 + 0, &kernel[6], 4);
|
ss0 += KERNEL1x3(in_1, x * 4 + 0, &kernel[6], 4);
|
||||||
ss1 += KERNEL1x3(in_1, x * 4 + 1, &kernel[6], 4);
|
ss1 += KERNEL1x3(in_1, x * 4 + 1, &kernel[6], 4);
|
||||||
ss2 += KERNEL1x3(in_1, x * 4 + 2, &kernel[6], 4);
|
ss2 += KERNEL1x3(in_1, x * 4 + 2, &kernel[6], 4);
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0);
|
||||||
clip8(ss0), clip8(ss1), clip8(ss2), 0);
|
|
||||||
memcpy(out + x * sizeof(v), &v, sizeof(v));
|
memcpy(out + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (im->bands == 4) {
|
} else if (im->bands == 4) {
|
||||||
|
@ -187,8 +182,7 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel,
|
||||||
ss1 += KERNEL1x3(in_1, x * 4 + 1, &kernel[6], 4);
|
ss1 += KERNEL1x3(in_1, x * 4 + 1, &kernel[6], 4);
|
||||||
ss2 += KERNEL1x3(in_1, x * 4 + 2, &kernel[6], 4);
|
ss2 += KERNEL1x3(in_1, x * 4 + 2, &kernel[6], 4);
|
||||||
ss3 += KERNEL1x3(in_1, x * 4 + 3, &kernel[6], 4);
|
ss3 += KERNEL1x3(in_1, x * 4 + 3, &kernel[6], 4);
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3));
|
||||||
clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3));
|
|
||||||
memcpy(out + x * sizeof(v), &v, sizeof(v));
|
memcpy(out + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,15 +192,11 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel,
|
||||||
memcpy(imOut->image[y], im->image[y], im->linesize);
|
memcpy(imOut->image[y], im->image[y], im->linesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel,
|
ImagingFilter5x5(Imaging imOut, Imaging im, const float *kernel, float offset) {
|
||||||
float offset)
|
#define KERNEL1x5(in0, x, kernel, d) \
|
||||||
{
|
(_i2f((UINT8)in0[x - d - d]) * (kernel)[0] + \
|
||||||
#define KERNEL1x5(in0, x, kernel, d) ( \
|
_i2f((UINT8)in0[x - d]) * (kernel)[1] + _i2f((UINT8)in0[x]) * (kernel)[2] + \
|
||||||
_i2f((UINT8) in0[x-d-d]) * (kernel)[0] + \
|
|
||||||
_i2f((UINT8) in0[x-d]) * (kernel)[1] + \
|
|
||||||
_i2f((UINT8) in0[x]) * (kernel)[2] + \
|
|
||||||
_i2f((UINT8)in0[x + d]) * (kernel)[3] + \
|
_i2f((UINT8)in0[x + d]) * (kernel)[3] + \
|
||||||
_i2f((UINT8)in0[x + d + d]) * (kernel)[4])
|
_i2f((UINT8)in0[x + d + d]) * (kernel)[4])
|
||||||
|
|
||||||
|
@ -290,8 +280,7 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel,
|
||||||
ss0 += KERNEL1x5(in_2, x * 4 + 0, &kernel[20], 4);
|
ss0 += KERNEL1x5(in_2, x * 4 + 0, &kernel[20], 4);
|
||||||
ss1 += KERNEL1x5(in_2, x * 4 + 1, &kernel[20], 4);
|
ss1 += KERNEL1x5(in_2, x * 4 + 1, &kernel[20], 4);
|
||||||
ss2 += KERNEL1x5(in_2, x * 4 + 2, &kernel[20], 4);
|
ss2 += KERNEL1x5(in_2, x * 4 + 2, &kernel[20], 4);
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0);
|
||||||
clip8(ss0), clip8(ss1), clip8(ss2), 0);
|
|
||||||
memcpy(out + x * sizeof(v), &v, sizeof(v));
|
memcpy(out + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (im->bands == 4) {
|
} else if (im->bands == 4) {
|
||||||
|
@ -321,12 +310,12 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel,
|
||||||
ss1 += KERNEL1x5(in_2, x * 4 + 1, &kernel[20], 4);
|
ss1 += KERNEL1x5(in_2, x * 4 + 1, &kernel[20], 4);
|
||||||
ss2 += KERNEL1x5(in_2, x * 4 + 2, &kernel[20], 4);
|
ss2 += KERNEL1x5(in_2, x * 4 + 2, &kernel[20], 4);
|
||||||
ss3 += KERNEL1x5(in_2, x * 4 + 3, &kernel[20], 4);
|
ss3 += KERNEL1x5(in_2, x * 4 + 3, &kernel[20], 4);
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3));
|
||||||
clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3));
|
|
||||||
memcpy(out + x * sizeof(v), &v, sizeof(v));
|
memcpy(out + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy(out + x * sizeof(UINT32), in0 + x * sizeof(UINT32), sizeof(UINT32) * 2);
|
memcpy(
|
||||||
|
out + x * sizeof(UINT32), in0 + x * sizeof(UINT32), sizeof(UINT32) * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy(imOut->image[y], im->image[y], im->linesize);
|
memcpy(imOut->image[y], im->image[y], im->linesize);
|
||||||
|
@ -334,9 +323,7 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel,
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32* kernel,
|
ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 offset) {
|
||||||
FLOAT32 offset)
|
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
|
|
||||||
|
@ -368,4 +355,3 @@ ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32* kernel,
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,11 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
#define I16(ptr) ((ptr)[0] + ((ptr)[1] << 8))
|
||||||
|
|
||||||
#define I16(ptr)\
|
#define I32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
|
||||||
((ptr)[0] + ((ptr)[1] << 8))
|
|
||||||
|
|
||||||
#define I32(ptr)\
|
|
||||||
((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
|
|
||||||
|
|
||||||
#define ERR_IF_DATA_OOB(offset) \
|
#define ERR_IF_DATA_OOB(offset) \
|
||||||
if ((data + (offset)) > ptr + bytes) { \
|
if ((data + (offset)) > ptr + bytes) { \
|
||||||
|
@ -31,8 +27,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
int framesize;
|
int framesize;
|
||||||
int c, chunks, advance;
|
int c, chunks, advance;
|
||||||
|
@ -80,18 +75,21 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
}
|
}
|
||||||
data = ptr + 6;
|
data = ptr + 6;
|
||||||
switch (I16(ptr + 4)) {
|
switch (I16(ptr + 4)) {
|
||||||
case 4: case 11:
|
case 4:
|
||||||
|
case 11:
|
||||||
/* FLI COLOR chunk */
|
/* FLI COLOR chunk */
|
||||||
break; /* ignored; handled by Python code */
|
break; /* ignored; handled by Python code */
|
||||||
case 7:
|
case 7:
|
||||||
/* FLI SS2 chunk (word delta) */
|
/* FLI SS2 chunk (word delta) */
|
||||||
/* OOB ok, we've got 4 bytes min on entry */
|
/* OOB ok, we've got 4 bytes min on entry */
|
||||||
lines = I16(data); data += 2;
|
lines = I16(data);
|
||||||
|
data += 2;
|
||||||
for (l = y = 0; l < lines && y < state->ysize; l++, y++) {
|
for (l = y = 0; l < lines && y < state->ysize; l++, y++) {
|
||||||
UINT8 *local_buf = (UINT8 *)im->image[y];
|
UINT8 *local_buf = (UINT8 *)im->image[y];
|
||||||
int p, packets;
|
int p, packets;
|
||||||
ERR_IF_DATA_OOB(2)
|
ERR_IF_DATA_OOB(2)
|
||||||
packets = I16(data); data += 2;
|
packets = I16(data);
|
||||||
|
data += 2;
|
||||||
while (packets & 0x8000) {
|
while (packets & 0x8000) {
|
||||||
/* flag word */
|
/* flag word */
|
||||||
if (packets & 0x4000) {
|
if (packets & 0x4000) {
|
||||||
|
@ -106,7 +104,8 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
local_buf[state->xsize - 1] = (UINT8)packets;
|
local_buf[state->xsize - 1] = (UINT8)packets;
|
||||||
}
|
}
|
||||||
ERR_IF_DATA_OOB(2)
|
ERR_IF_DATA_OOB(2)
|
||||||
packets = I16(data); data += 2;
|
packets = I16(data);
|
||||||
|
data += 2;
|
||||||
}
|
}
|
||||||
for (p = x = 0; p < packets; p++) {
|
for (p = x = 0; p < packets; p++) {
|
||||||
ERR_IF_DATA_OOB(2)
|
ERR_IF_DATA_OOB(2)
|
||||||
|
@ -146,7 +145,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
case 12:
|
case 12:
|
||||||
/* FLI LC chunk (byte delta) */
|
/* FLI LC chunk (byte delta) */
|
||||||
/* OOB Check ok, we have 4 bytes min here */
|
/* OOB Check ok, we have 4 bytes min here */
|
||||||
y = I16(data); ymax = y + I16(data+2); data += 4;
|
y = I16(data);
|
||||||
|
ymax = y + I16(data + 2);
|
||||||
|
data += 4;
|
||||||
for (; y < ymax && y < state->ysize; y++) {
|
for (; y < ymax && y < state->ysize; y++) {
|
||||||
UINT8 *out = (UINT8 *)im->image[y];
|
UINT8 *out = (UINT8 *)im->image[y];
|
||||||
ERR_IF_DATA_OOB(1)
|
ERR_IF_DATA_OOB(1)
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
/* Transpose operations */
|
/* Transpose operations */
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingFlipLeftRight(Imaging imOut, Imaging imIn)
|
ImagingFlipLeftRight(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xr;
|
int x, y, xr;
|
||||||
|
|
||||||
|
@ -58,10 +57,8 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingFlipTopBottom(Imaging imOut, Imaging imIn)
|
ImagingFlipTopBottom(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int y, yr;
|
int y, yr;
|
||||||
|
|
||||||
|
@ -86,10 +83,8 @@ ImagingFlipTopBottom(Imaging imOut, Imaging imIn)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingRotate90(Imaging imOut, Imaging imIn)
|
ImagingRotate90(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xx, yy, xr, xxsize, yysize;
|
int x, y, xx, yy, xr, xxsize, yysize;
|
||||||
int xxx, yyy, xxxsize, yyysize;
|
int xxx, yyy, xxxsize, yyysize;
|
||||||
|
@ -110,8 +105,12 @@ ImagingRotate90(Imaging imOut, Imaging imIn)
|
||||||
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
||||||
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
||||||
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
||||||
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize ? yy + ROTATE_SMALL_CHUNK : imIn->ysize; \
|
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize \
|
||||||
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize ? xx + ROTATE_SMALL_CHUNK : imIn->xsize; \
|
? yy + ROTATE_SMALL_CHUNK \
|
||||||
|
: imIn->ysize; \
|
||||||
|
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize \
|
||||||
|
? xx + ROTATE_SMALL_CHUNK \
|
||||||
|
: imIn->xsize; \
|
||||||
for (yyy = yy; yyy < yyysize; yyy++) { \
|
for (yyy = yy; yyy < yyysize; yyy++) { \
|
||||||
INT *in = (INT *)imIn->image[yyy]; \
|
INT *in = (INT *)imIn->image[yyy]; \
|
||||||
xr = imIn->xsize - 1 - xx; \
|
xr = imIn->xsize - 1 - xx; \
|
||||||
|
@ -144,10 +143,8 @@ ImagingRotate90(Imaging imOut, Imaging imIn)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingTranspose(Imaging imOut, Imaging imIn)
|
ImagingTranspose(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xx, yy, xxsize, yysize;
|
int x, y, xx, yy, xxsize, yysize;
|
||||||
int xxx, yyy, xxxsize, yyysize;
|
int xxx, yyy, xxxsize, yyysize;
|
||||||
|
@ -168,8 +165,12 @@ ImagingTranspose(Imaging imOut, Imaging imIn)
|
||||||
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
||||||
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
||||||
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
||||||
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize ? yy + ROTATE_SMALL_CHUNK : imIn->ysize; \
|
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize \
|
||||||
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize ? xx + ROTATE_SMALL_CHUNK : imIn->xsize; \
|
? yy + ROTATE_SMALL_CHUNK \
|
||||||
|
: imIn->ysize; \
|
||||||
|
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize \
|
||||||
|
? xx + ROTATE_SMALL_CHUNK \
|
||||||
|
: imIn->xsize; \
|
||||||
for (yyy = yy; yyy < yyysize; yyy++) { \
|
for (yyy = yy; yyy < yyysize; yyy++) { \
|
||||||
INT *in = (INT *)imIn->image[yyy]; \
|
INT *in = (INT *)imIn->image[yyy]; \
|
||||||
for (xxx = xx; xxx < xxxsize; xxx++) { \
|
for (xxx = xx; xxx < xxxsize; xxx++) { \
|
||||||
|
@ -201,10 +202,8 @@ ImagingTranspose(Imaging imOut, Imaging imIn)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingTransverse(Imaging imOut, Imaging imIn)
|
ImagingTransverse(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xr, yr, xx, yy, xxsize, yysize;
|
int x, y, xr, yr, xx, yy, xxsize, yysize;
|
||||||
int xxx, yyy, xxxsize, yyysize;
|
int xxx, yyy, xxxsize, yyysize;
|
||||||
|
@ -225,8 +224,12 @@ ImagingTransverse(Imaging imOut, Imaging imIn)
|
||||||
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
||||||
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
||||||
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
||||||
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize ? yy + ROTATE_SMALL_CHUNK : imIn->ysize; \
|
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize \
|
||||||
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize ? xx + ROTATE_SMALL_CHUNK : imIn->xsize; \
|
? yy + ROTATE_SMALL_CHUNK \
|
||||||
|
: imIn->ysize; \
|
||||||
|
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize \
|
||||||
|
? xx + ROTATE_SMALL_CHUNK \
|
||||||
|
: imIn->xsize; \
|
||||||
yr = imIn->ysize - 1 - yy; \
|
yr = imIn->ysize - 1 - yy; \
|
||||||
for (yyy = yy; yyy < yyysize; yyy++, yr--) { \
|
for (yyy = yy; yyy < yyysize; yyy++, yr--) { \
|
||||||
INT *in = (INT *)imIn->image[yyy]; \
|
INT *in = (INT *)imIn->image[yyy]; \
|
||||||
|
@ -260,10 +263,8 @@ ImagingTransverse(Imaging imOut, Imaging imIn)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingRotate180(Imaging imOut, Imaging imIn)
|
ImagingRotate180(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xr, yr;
|
int x, y, xr, yr;
|
||||||
|
|
||||||
|
@ -306,10 +307,8 @@ ImagingRotate180(Imaging imOut, Imaging imIn)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingRotate270(Imaging imOut, Imaging imIn)
|
ImagingRotate270(Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, xx, yy, yr, xxsize, yysize;
|
int x, y, xx, yy, yr, xxsize, yysize;
|
||||||
int xxx, yyy, xxxsize, yyysize;
|
int xxx, yyy, xxxsize, yyysize;
|
||||||
|
@ -330,8 +329,12 @@ ImagingRotate270(Imaging imOut, Imaging imIn)
|
||||||
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
xxsize = x + ROTATE_CHUNK < imIn->xsize ? x + ROTATE_CHUNK : imIn->xsize; \
|
||||||
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
for (yy = y; yy < yysize; yy += ROTATE_SMALL_CHUNK) { \
|
||||||
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
for (xx = x; xx < xxsize; xx += ROTATE_SMALL_CHUNK) { \
|
||||||
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize ? yy + ROTATE_SMALL_CHUNK : imIn->ysize; \
|
yyysize = yy + ROTATE_SMALL_CHUNK < imIn->ysize \
|
||||||
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize ? xx + ROTATE_SMALL_CHUNK : imIn->xsize; \
|
? yy + ROTATE_SMALL_CHUNK \
|
||||||
|
: imIn->ysize; \
|
||||||
|
xxxsize = xx + ROTATE_SMALL_CHUNK < imIn->xsize \
|
||||||
|
? xx + ROTATE_SMALL_CHUNK \
|
||||||
|
: imIn->xsize; \
|
||||||
yr = imIn->ysize - 1 - yy; \
|
yr = imIn->ysize - 1 - yy; \
|
||||||
for (yyy = yy; yyy < yyysize; yyy++, yr--) { \
|
for (yyy = yy; yyy < yyysize; yyy++, yr--) { \
|
||||||
INT *in = (INT *)imIn->image[yyy]; \
|
INT *in = (INT *)imIn->image[yyy]; \
|
||||||
|
@ -364,22 +367,24 @@ ImagingRotate270(Imaging imOut, Imaging imIn)
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Transforms */
|
/* Transforms */
|
||||||
|
|
||||||
/* transform primitives (ImagingTransformMap) */
|
/* transform primitives (ImagingTransformMap) */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
affine_transform(double* xout, double* yout, int x, int y, void* data)
|
affine_transform(double *xout, double *yout, int x, int y, void *data) {
|
||||||
{
|
|
||||||
/* full moon tonight. your compiler will generate bogus code
|
/* full moon tonight. your compiler will generate bogus code
|
||||||
for simple expressions, unless you reorganize the code, or
|
for simple expressions, unless you reorganize the code, or
|
||||||
install Service Pack 3 */
|
install Service Pack 3 */
|
||||||
|
|
||||||
double *a = (double *)data;
|
double *a = (double *)data;
|
||||||
double a0 = a[0]; double a1 = a[1]; double a2 = a[2];
|
double a0 = a[0];
|
||||||
double a3 = a[3]; double a4 = a[4]; double a5 = a[5];
|
double a1 = a[1];
|
||||||
|
double a2 = a[2];
|
||||||
|
double a3 = a[3];
|
||||||
|
double a4 = a[4];
|
||||||
|
double a5 = a[5];
|
||||||
|
|
||||||
double xin = x + 0.5;
|
double xin = x + 0.5;
|
||||||
double yin = y + 0.5;
|
double yin = y + 0.5;
|
||||||
|
@ -391,12 +396,16 @@ affine_transform(double* xout, double* yout, int x, int y, void* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
perspective_transform(double* xout, double* yout, int x, int y, void* data)
|
perspective_transform(double *xout, double *yout, int x, int y, void *data) {
|
||||||
{
|
|
||||||
double *a = (double *)data;
|
double *a = (double *)data;
|
||||||
double a0 = a[0]; double a1 = a[1]; double a2 = a[2];
|
double a0 = a[0];
|
||||||
double a3 = a[3]; double a4 = a[4]; double a5 = a[5];
|
double a1 = a[1];
|
||||||
double a6 = a[6]; double a7 = a[7];
|
double a2 = a[2];
|
||||||
|
double a3 = a[3];
|
||||||
|
double a4 = a[4];
|
||||||
|
double a5 = a[5];
|
||||||
|
double a6 = a[6];
|
||||||
|
double a7 = a[7];
|
||||||
|
|
||||||
double xin = x + 0.5;
|
double xin = x + 0.5;
|
||||||
double yin = y + 0.5;
|
double yin = y + 0.5;
|
||||||
|
@ -408,13 +417,18 @@ perspective_transform(double* xout, double* yout, int x, int y, void* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
quad_transform(double* xout, double* yout, int x, int y, void* data)
|
quad_transform(double *xout, double *yout, int x, int y, void *data) {
|
||||||
{
|
|
||||||
/* quad warp: map quadrilateral to rectangle */
|
/* quad warp: map quadrilateral to rectangle */
|
||||||
|
|
||||||
double *a = (double *)data;
|
double *a = (double *)data;
|
||||||
double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; double a3 = a[3];
|
double a0 = a[0];
|
||||||
double a4 = a[4]; double a5 = a[5]; double a6 = a[6]; double a7 = a[7];
|
double a1 = a[1];
|
||||||
|
double a2 = a[2];
|
||||||
|
double a3 = a[3];
|
||||||
|
double a4 = a[4];
|
||||||
|
double a5 = a[5];
|
||||||
|
double a6 = a[6];
|
||||||
|
double a7 = a[7];
|
||||||
|
|
||||||
double xin = x + 0.5;
|
double xin = x + 0.5;
|
||||||
double yin = y + 0.5;
|
double yin = y + 0.5;
|
||||||
|
@ -428,8 +442,7 @@ quad_transform(double* xout, double* yout, int x, int y, void* data)
|
||||||
/* transform filters (ImagingTransformFilter) */
|
/* transform filters (ImagingTransformFilter) */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nearest_filter8(void* out, Imaging im, double xin, double yin)
|
nearest_filter8(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
int x = COORD(xin);
|
int x = COORD(xin);
|
||||||
int y = COORD(yin);
|
int y = COORD(yin);
|
||||||
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
|
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
|
||||||
|
@ -440,8 +453,7 @@ nearest_filter8(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nearest_filter16(void* out, Imaging im, double xin, double yin)
|
nearest_filter16(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
int x = COORD(xin);
|
int x = COORD(xin);
|
||||||
int y = COORD(yin);
|
int y = COORD(yin);
|
||||||
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
|
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
|
||||||
|
@ -452,8 +464,7 @@ nearest_filter16(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nearest_filter32(void* out, Imaging im, double xin, double yin)
|
nearest_filter32(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
int x = COORD(xin);
|
int x = COORD(xin);
|
||||||
int y = COORD(yin);
|
int y = COORD(yin);
|
||||||
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
|
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
|
||||||
|
@ -466,8 +477,7 @@ nearest_filter32(void* out, Imaging im, double xin, double yin)
|
||||||
#define XCLIP(im, x) (((x) < 0) ? 0 : ((x) < im->xsize) ? (x) : im->xsize - 1)
|
#define XCLIP(im, x) (((x) < 0) ? 0 : ((x) < im->xsize) ? (x) : im->xsize - 1)
|
||||||
#define YCLIP(im, y) (((y) < 0) ? 0 : ((y) < im->ysize) ? (y) : im->ysize - 1)
|
#define YCLIP(im, y) (((y) < 0) ? 0 : ((y) < im->ysize) ? (y) : im->ysize - 1)
|
||||||
|
|
||||||
#define BILINEAR(v, a, b, d)\
|
#define BILINEAR(v, a, b, d) (v = (a) + ((b) - (a)) * (d))
|
||||||
(v = (a) + ( (b) - (a) ) * (d))
|
|
||||||
|
|
||||||
#define BILINEAR_HEAD(type) \
|
#define BILINEAR_HEAD(type) \
|
||||||
int x, y; \
|
int x, y; \
|
||||||
|
@ -485,7 +495,8 @@ nearest_filter32(void* out, Imaging im, double xin, double yin)
|
||||||
dx = xin - x; \
|
dx = xin - x; \
|
||||||
dy = yin - y;
|
dy = yin - y;
|
||||||
|
|
||||||
#define BILINEAR_BODY(type, image, step, offset) {\
|
#define BILINEAR_BODY(type, image, step, offset) \
|
||||||
|
{ \
|
||||||
in = (type *)((image)[YCLIP(im, y)] + offset); \
|
in = (type *)((image)[YCLIP(im, y)] + offset); \
|
||||||
x0 = XCLIP(im, x + 0) * step; \
|
x0 = XCLIP(im, x + 0) * step; \
|
||||||
x1 = XCLIP(im, x + 1) * step; \
|
x1 = XCLIP(im, x + 1) * step; \
|
||||||
|
@ -500,8 +511,7 @@ nearest_filter32(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bilinear_filter8(void* out, Imaging im, double xin, double yin)
|
bilinear_filter8(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
BILINEAR_HEAD(UINT8);
|
BILINEAR_HEAD(UINT8);
|
||||||
BILINEAR_BODY(UINT8, im->image8, 1, 0);
|
BILINEAR_BODY(UINT8, im->image8, 1, 0);
|
||||||
((UINT8 *)out)[0] = (UINT8)v1;
|
((UINT8 *)out)[0] = (UINT8)v1;
|
||||||
|
@ -509,8 +519,7 @@ bilinear_filter8(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bilinear_filter32I(void* out, Imaging im, double xin, double yin)
|
bilinear_filter32I(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
INT32 k;
|
INT32 k;
|
||||||
BILINEAR_HEAD(INT32);
|
BILINEAR_HEAD(INT32);
|
||||||
BILINEAR_BODY(INT32, im->image32, 1, 0);
|
BILINEAR_BODY(INT32, im->image32, 1, 0);
|
||||||
|
@ -520,8 +529,7 @@ bilinear_filter32I(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bilinear_filter32F(void* out, Imaging im, double xin, double yin)
|
bilinear_filter32F(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
FLOAT32 k;
|
FLOAT32 k;
|
||||||
BILINEAR_HEAD(FLOAT32);
|
BILINEAR_HEAD(FLOAT32);
|
||||||
BILINEAR_BODY(FLOAT32, im->image32, 1, 0);
|
BILINEAR_BODY(FLOAT32, im->image32, 1, 0);
|
||||||
|
@ -531,8 +539,7 @@ bilinear_filter32F(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bilinear_filter32LA(void* out, Imaging im, double xin, double yin)
|
bilinear_filter32LA(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
BILINEAR_HEAD(UINT8);
|
BILINEAR_HEAD(UINT8);
|
||||||
BILINEAR_BODY(UINT8, im->image, 4, 0);
|
BILINEAR_BODY(UINT8, im->image, 4, 0);
|
||||||
((UINT8 *)out)[0] = (UINT8)v1;
|
((UINT8 *)out)[0] = (UINT8)v1;
|
||||||
|
@ -544,8 +551,7 @@ bilinear_filter32LA(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bilinear_filter32RGB(void* out, Imaging im, double xin, double yin)
|
bilinear_filter32RGB(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
int b;
|
int b;
|
||||||
BILINEAR_HEAD(UINT8);
|
BILINEAR_HEAD(UINT8);
|
||||||
for (b = 0; b < im->bands; b++) {
|
for (b = 0; b < im->bands; b++) {
|
||||||
|
@ -559,7 +565,8 @@ bilinear_filter32RGB(void* out, Imaging im, double xin, double yin)
|
||||||
#undef BILINEAR_HEAD
|
#undef BILINEAR_HEAD
|
||||||
#undef BILINEAR_BODY
|
#undef BILINEAR_BODY
|
||||||
|
|
||||||
#define BICUBIC(v, v1, v2, v3, v4, d) {\
|
#define BICUBIC(v, v1, v2, v3, v4, d) \
|
||||||
|
{ \
|
||||||
double p1 = v2; \
|
double p1 = v2; \
|
||||||
double p2 = -v1 + v3; \
|
double p2 = -v1 + v3; \
|
||||||
double p3 = 2 * (v1 - v2) + v3 - v4; \
|
double p3 = 2 * (v1 - v2) + v3 - v4; \
|
||||||
|
@ -583,9 +590,11 @@ bilinear_filter32RGB(void* out, Imaging im, double xin, double yin)
|
||||||
y = FLOOR(yin); \
|
y = FLOOR(yin); \
|
||||||
dx = xin - x; \
|
dx = xin - x; \
|
||||||
dy = yin - y; \
|
dy = yin - y; \
|
||||||
x--; y--;
|
x--; \
|
||||||
|
y--;
|
||||||
|
|
||||||
#define BICUBIC_BODY(type, image, step, offset) {\
|
#define BICUBIC_BODY(type, image, step, offset) \
|
||||||
|
{ \
|
||||||
in = (type *)((image)[YCLIP(im, y)] + offset); \
|
in = (type *)((image)[YCLIP(im, y)] + offset); \
|
||||||
x0 = XCLIP(im, x + 0) * step; \
|
x0 = XCLIP(im, x + 0) * step; \
|
||||||
x1 = XCLIP(im, x + 1) * step; \
|
x1 = XCLIP(im, x + 1) * step; \
|
||||||
|
@ -613,10 +622,8 @@ bilinear_filter32RGB(void* out, Imaging im, double xin, double yin)
|
||||||
BICUBIC(v1, v1, v2, v3, v4, dy); \
|
BICUBIC(v1, v1, v2, v3, v4, dy); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bicubic_filter8(void* out, Imaging im, double xin, double yin)
|
bicubic_filter8(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
BICUBIC_HEAD(UINT8);
|
BICUBIC_HEAD(UINT8);
|
||||||
BICUBIC_BODY(UINT8, im->image8, 1, 0);
|
BICUBIC_BODY(UINT8, im->image8, 1, 0);
|
||||||
if (v1 <= 0.0) {
|
if (v1 <= 0.0) {
|
||||||
|
@ -630,8 +637,7 @@ bicubic_filter8(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bicubic_filter32I(void* out, Imaging im, double xin, double yin)
|
bicubic_filter32I(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
INT32 k;
|
INT32 k;
|
||||||
BICUBIC_HEAD(INT32);
|
BICUBIC_HEAD(INT32);
|
||||||
BICUBIC_BODY(INT32, im->image32, 1, 0);
|
BICUBIC_BODY(INT32, im->image32, 1, 0);
|
||||||
|
@ -641,8 +647,7 @@ bicubic_filter32I(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bicubic_filter32F(void* out, Imaging im, double xin, double yin)
|
bicubic_filter32F(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
FLOAT32 k;
|
FLOAT32 k;
|
||||||
BICUBIC_HEAD(FLOAT32);
|
BICUBIC_HEAD(FLOAT32);
|
||||||
BICUBIC_BODY(FLOAT32, im->image32, 1, 0);
|
BICUBIC_BODY(FLOAT32, im->image32, 1, 0);
|
||||||
|
@ -652,8 +657,7 @@ bicubic_filter32F(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bicubic_filter32LA(void* out, Imaging im, double xin, double yin)
|
bicubic_filter32LA(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
BICUBIC_HEAD(UINT8);
|
BICUBIC_HEAD(UINT8);
|
||||||
BICUBIC_BODY(UINT8, im->image, 4, 0);
|
BICUBIC_BODY(UINT8, im->image, 4, 0);
|
||||||
if (v1 <= 0.0) {
|
if (v1 <= 0.0) {
|
||||||
|
@ -681,8 +685,7 @@ bicubic_filter32LA(void* out, Imaging im, double xin, double yin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bicubic_filter32RGB(void* out, Imaging im, double xin, double yin)
|
bicubic_filter32RGB(void *out, Imaging im, double xin, double yin) {
|
||||||
{
|
|
||||||
int b;
|
int b;
|
||||||
BICUBIC_HEAD(UINT8);
|
BICUBIC_HEAD(UINT8);
|
||||||
for (b = 0; b < im->bands; b++) {
|
for (b = 0; b < im->bands; b++) {
|
||||||
|
@ -703,8 +706,7 @@ bicubic_filter32RGB(void* out, Imaging im, double xin, double yin)
|
||||||
#undef BICUBIC_BODY
|
#undef BICUBIC_BODY
|
||||||
|
|
||||||
static ImagingTransformFilter
|
static ImagingTransformFilter
|
||||||
getfilter(Imaging im, int filterid)
|
getfilter(Imaging im, int filterid) {
|
||||||
{
|
|
||||||
switch (filterid) {
|
switch (filterid) {
|
||||||
case IMAGING_TRANSFORM_NEAREST:
|
case IMAGING_TRANSFORM_NEAREST:
|
||||||
if (im->image8) {
|
if (im->image8) {
|
||||||
|
@ -770,10 +772,16 @@ getfilter(Imaging im, int filterid)
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingGenericTransform(
|
ImagingGenericTransform(
|
||||||
Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1,
|
Imaging imOut,
|
||||||
ImagingTransformMap transform, void* transform_data,
|
Imaging imIn,
|
||||||
int filterid, int fill)
|
int x0,
|
||||||
{
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
ImagingTransformMap transform,
|
||||||
|
void *transform_data,
|
||||||
|
int filterid,
|
||||||
|
int fill) {
|
||||||
/* slow generic transformation. use ImagingTransformAffine or
|
/* slow generic transformation. use ImagingTransformAffine or
|
||||||
ImagingScaleAffine where possible. */
|
ImagingScaleAffine where possible. */
|
||||||
|
|
||||||
|
@ -827,10 +835,15 @@ ImagingGenericTransform(
|
||||||
}
|
}
|
||||||
|
|
||||||
static Imaging
|
static Imaging
|
||||||
ImagingScaleAffine(Imaging imOut, Imaging imIn,
|
ImagingScaleAffine(
|
||||||
int x0, int y0, int x1, int y1,
|
Imaging imOut,
|
||||||
double a[6], int fill)
|
Imaging imIn,
|
||||||
{
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
double a[6],
|
||||||
|
int fill) {
|
||||||
/* scale, nearest neighbour resampling */
|
/* scale, nearest neighbour resampling */
|
||||||
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
|
@ -920,17 +933,23 @@ ImagingScaleAffine(Imaging imOut, Imaging imIn,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
check_fixed(double a[6], int x, int y)
|
check_fixed(double a[6], int x, int y) {
|
||||||
{
|
return (
|
||||||
return (fabs(x*a[0] + y*a[1] + a[2]) < 32768.0 &&
|
fabs(x * a[0] + y * a[1] + a[2]) < 32768.0 &&
|
||||||
fabs(x * a[3] + y * a[4] + a[5]) < 32768.0);
|
fabs(x * a[3] + y * a[4] + a[5]) < 32768.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Imaging
|
static inline Imaging
|
||||||
affine_fixed(Imaging imOut, Imaging imIn,
|
affine_fixed(
|
||||||
int x0, int y0, int x1, int y1,
|
Imaging imOut,
|
||||||
double a[6], int filterid, int fill)
|
Imaging imIn,
|
||||||
{
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
double a[6],
|
||||||
|
int filterid,
|
||||||
|
int fill) {
|
||||||
/* affine transform, nearest neighbour resampling, fixed point
|
/* affine transform, nearest neighbour resampling, fixed point
|
||||||
arithmetics */
|
arithmetics */
|
||||||
|
|
||||||
|
@ -949,8 +968,10 @@ affine_fixed(Imaging imOut, Imaging imIn,
|
||||||
/* use 16.16 fixed point arithmetics */
|
/* use 16.16 fixed point arithmetics */
|
||||||
#define FIX(v) FLOOR((v)*65536.0 + 0.5)
|
#define FIX(v) FLOOR((v)*65536.0 + 0.5)
|
||||||
|
|
||||||
a0 = FIX(a[0]); a1 = FIX(a[1]);
|
a0 = FIX(a[0]);
|
||||||
a3 = FIX(a[3]); a4 = FIX(a[4]);
|
a1 = FIX(a[1]);
|
||||||
|
a3 = FIX(a[3]);
|
||||||
|
a4 = FIX(a[4]);
|
||||||
a2 = FIX(a[2] + a[0] * 0.5 + a[1] * 0.5);
|
a2 = FIX(a[2] + a[0] * 0.5 + a[1] * 0.5);
|
||||||
a5 = FIX(a[5] + a[3] * 0.5 + a[4] * 0.5);
|
a5 = FIX(a[5] + a[3] * 0.5 + a[4] * 0.5);
|
||||||
|
|
||||||
|
@ -996,10 +1017,16 @@ affine_fixed(Imaging imOut, Imaging imIn,
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingTransformAffine(Imaging imOut, Imaging imIn,
|
ImagingTransformAffine(
|
||||||
int x0, int y0, int x1, int y1,
|
Imaging imOut,
|
||||||
double a[6], int filterid, int fill)
|
Imaging imIn,
|
||||||
{
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
double a[6],
|
||||||
|
int filterid,
|
||||||
|
int fill) {
|
||||||
/* affine transform, nearest neighbour resampling, floating point
|
/* affine transform, nearest neighbour resampling, floating point
|
||||||
arithmetics*/
|
arithmetics*/
|
||||||
|
|
||||||
|
@ -1012,10 +1039,7 @@ ImagingTransformAffine(Imaging imOut, Imaging imIn,
|
||||||
|
|
||||||
if (filterid || imIn->type == IMAGING_TYPE_SPECIAL) {
|
if (filterid || imIn->type == IMAGING_TYPE_SPECIAL) {
|
||||||
return ImagingGenericTransform(
|
return ImagingGenericTransform(
|
||||||
imOut, imIn,
|
imOut, imIn, x0, y0, x1, y1, affine_transform, a, filterid, fill);
|
||||||
x0, y0, x1, y1,
|
|
||||||
affine_transform, a,
|
|
||||||
filterid, fill);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a[1] == 0 && a[3] == 0) {
|
if (a[1] == 0 && a[3] == 0) {
|
||||||
|
@ -1100,10 +1124,17 @@ ImagingTransformAffine(Imaging imOut, Imaging imIn,
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingTransform(Imaging imOut, Imaging imIn, int method,
|
ImagingTransform(
|
||||||
int x0, int y0, int x1, int y1,
|
Imaging imOut,
|
||||||
double a[8], int filterid, int fill)
|
Imaging imIn,
|
||||||
{
|
int method,
|
||||||
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
double a[8],
|
||||||
|
int filterid,
|
||||||
|
int fill) {
|
||||||
ImagingTransformMap transform;
|
ImagingTransformMap transform;
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
|
@ -1122,7 +1153,5 @@ ImagingTransform(Imaging imOut, Imaging imIn, int method,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImagingGenericTransform(
|
return ImagingGenericTransform(
|
||||||
imOut, imIn,
|
imOut, imIn, x0, y0, x1, y1, transform, a, filterid, fill);
|
||||||
x0, y0, x1, y1,
|
|
||||||
transform, a, filterid, fill);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,10 @@
|
||||||
* See the README file for details on usage and redistribution.
|
* See the README file for details on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingGetBBox(Imaging im, int bbox[4])
|
ImagingGetBBox(Imaging im, int bbox[4]) {
|
||||||
{
|
|
||||||
/* Get the bounding box for any non-zero data in the image.*/
|
/* Get the bounding box for any non-zero data in the image.*/
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -61,10 +58,9 @@ ImagingGetBBox(Imaging im, int bbox[4])
|
||||||
INT32 mask = 0xffffffff;
|
INT32 mask = 0xffffffff;
|
||||||
if (im->bands == 3) {
|
if (im->bands == 3) {
|
||||||
((UINT8 *)&mask)[3] = 0;
|
((UINT8 *)&mask)[3] = 0;
|
||||||
} else if (strcmp(im->mode, "RGBa") == 0 ||
|
} else if (
|
||||||
strcmp(im->mode, "RGBA") == 0 ||
|
strcmp(im->mode, "RGBa") == 0 || strcmp(im->mode, "RGBA") == 0 ||
|
||||||
strcmp(im->mode, "La") == 0 ||
|
strcmp(im->mode, "La") == 0 || strcmp(im->mode, "LA") == 0 ||
|
||||||
strcmp(im->mode, "LA") == 0 ||
|
|
||||||
strcmp(im->mode, "PA") == 0) {
|
strcmp(im->mode, "PA") == 0) {
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
mask = 0x000000ff;
|
mask = 0x000000ff;
|
||||||
|
@ -83,10 +79,8 @@ ImagingGetBBox(Imaging im, int bbox[4])
|
||||||
return 1; /* ok */
|
return 1; /* ok */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj)
|
ImagingGetProjection(Imaging im, UINT8 *xproj, UINT8 *yproj) {
|
||||||
{
|
|
||||||
/* Get projection arrays for non-zero data in the image.*/
|
/* Get projection arrays for non-zero data in the image.*/
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -123,10 +117,8 @@ ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj)
|
||||||
return 1; /* ok */
|
return 1; /* ok */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingGetExtrema(Imaging im, void *extrema)
|
ImagingGetExtrema(Imaging im, void *extrema) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
INT32 imin, imax;
|
INT32 imin, imax;
|
||||||
FLOAT32 fmin, fmax;
|
FLOAT32 fmin, fmax;
|
||||||
|
@ -225,20 +217,18 @@ ImagingGetExtrema(Imaging im, void *extrema)
|
||||||
return 1; /* ok */
|
return 1; /* ok */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static ImagingColorItem* getcolors8(Imaging im, int maxcolors, int* size);*/
|
/* static ImagingColorItem* getcolors8(Imaging im, int maxcolors, int* size);*/
|
||||||
static ImagingColorItem* getcolors32(Imaging im, int maxcolors, int* size);
|
static ImagingColorItem *
|
||||||
|
getcolors32(Imaging im, int maxcolors, int *size);
|
||||||
|
|
||||||
ImagingColorItem *
|
ImagingColorItem *
|
||||||
ImagingGetColors(Imaging im, int maxcolors, int* size)
|
ImagingGetColors(Imaging im, int maxcolors, int *size) {
|
||||||
{
|
|
||||||
/* FIXME: add support for 8-bit images */
|
/* FIXME: add support for 8-bit images */
|
||||||
return getcolors32(im, maxcolors, size);
|
return getcolors32(im, maxcolors, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImagingColorItem *
|
static ImagingColorItem *
|
||||||
getcolors32(Imaging im, int maxcolors, int* size)
|
getcolors32(Imaging im, int maxcolors, int *size) {
|
||||||
{
|
|
||||||
unsigned int h;
|
unsigned int h;
|
||||||
unsigned int i, incr;
|
unsigned int i, incr;
|
||||||
int colors;
|
int colors;
|
||||||
|
@ -256,12 +246,12 @@ getcolors32(Imaging im, int maxcolors, int* size)
|
||||||
Python's Unicode property database (written by yours truly) /F */
|
Python's Unicode property database (written by yours truly) /F */
|
||||||
|
|
||||||
static int SIZES[] = {
|
static int SIZES[] = {
|
||||||
4,3, 8,3, 16,3, 32,5, 64,3, 128,3, 256,29, 512,17, 1024,9, 2048,5,
|
4, 3, 8, 3, 16, 3, 32, 5, 64, 3,
|
||||||
4096,83, 8192,27, 16384,43, 32768,3, 65536,45, 131072,9, 262144,39,
|
128, 3, 256, 29, 512, 17, 1024, 9, 2048, 5,
|
||||||
524288,39, 1048576,9, 2097152,5, 4194304,3, 8388608,33, 16777216,27,
|
4096, 83, 8192, 27, 16384, 43, 32768, 3, 65536, 45,
|
||||||
33554432,9, 67108864,71, 134217728,39, 268435456,9, 536870912,5,
|
131072, 9, 262144, 39, 524288, 39, 1048576, 9, 2097152, 5,
|
||||||
1073741824,83, 0
|
4194304, 3, 8388608, 33, 16777216, 27, 33554432, 9, 67108864, 71,
|
||||||
};
|
134217728, 39, 268435456, 9, 536870912, 5, 1073741824, 83, 0};
|
||||||
|
|
||||||
code_size = code_poly = code_mask = 0;
|
code_size = code_poly = code_mask = 0;
|
||||||
|
|
||||||
|
@ -309,7 +299,8 @@ getcolors32(Imaging im, int maxcolors, int* size)
|
||||||
if (colors++ == maxcolors) {
|
if (colors++ == maxcolors) {
|
||||||
goto overflow;
|
goto overflow;
|
||||||
}
|
}
|
||||||
v->x = x; v->y = y;
|
v->x = x;
|
||||||
|
v->y = y;
|
||||||
v->pixel = pixel;
|
v->pixel = pixel;
|
||||||
v->count = 1;
|
v->count = 1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -329,7 +320,8 @@ getcolors32(Imaging im, int maxcolors, int* size)
|
||||||
if (colors++ == maxcolors) {
|
if (colors++ == maxcolors) {
|
||||||
goto overflow;
|
goto overflow;
|
||||||
}
|
}
|
||||||
v->x = x; v->y = y;
|
v->x = x;
|
||||||
|
v->y = y;
|
||||||
v->pixel = pixel;
|
v->pixel = pixel;
|
||||||
v->count = 1;
|
v->count = 1;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
* Copyright (c) Fredrik Lundh 1995-96.
|
* Copyright (c) Fredrik Lundh 1995-96.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Max size for a LZW code word. */
|
/* Max size for a LZW code word. */
|
||||||
|
|
||||||
#define GIFBITS 12
|
#define GIFBITS 12
|
||||||
|
@ -15,9 +14,7 @@
|
||||||
#define GIFTABLE (1 << GIFBITS)
|
#define GIFTABLE (1 << GIFBITS)
|
||||||
#define GIFBUFFER (1 << GIFBITS)
|
#define GIFBUFFER (1 << GIFBITS)
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* CONFIGURATION */
|
/* CONFIGURATION */
|
||||||
|
|
||||||
/* Initial number of bits. The caller should clear all fields in
|
/* Initial number of bits. The caller should clear all fields in
|
||||||
|
@ -65,15 +62,13 @@ typedef struct {
|
||||||
|
|
||||||
} GIFDECODERSTATE;
|
} GIFDECODERSTATE;
|
||||||
|
|
||||||
typedef struct GIFENCODERBLOCK_T
|
typedef struct GIFENCODERBLOCK_T {
|
||||||
{
|
|
||||||
struct GIFENCODERBLOCK_T *next;
|
struct GIFENCODERBLOCK_T *next;
|
||||||
int size;
|
int size;
|
||||||
UINT8 data[255];
|
UINT8 data[255];
|
||||||
} GIFENCODERBLOCK;
|
} GIFENCODERBLOCK;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* CONFIGURATION */
|
/* CONFIGURATION */
|
||||||
|
|
||||||
/* Initial number of bits. The caller should clear all fields in
|
/* Initial number of bits. The caller should clear all fields in
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -29,12 +28,11 @@
|
||||||
|
|
||||||
#include "Gif.h"
|
#include "Gif.h"
|
||||||
|
|
||||||
|
#define NEWLINE(state, context) \
|
||||||
#define NEWLINE(state, context) {\
|
{ \
|
||||||
state->x = 0; \
|
state->x = 0; \
|
||||||
state->y += context->step; \
|
state->y += context->step; \
|
||||||
while (state->y >= state->ysize)\
|
while (state->y >= state->ysize) switch (context->interlace) { \
|
||||||
switch (context->interlace) {\
|
|
||||||
case 1: \
|
case 1: \
|
||||||
context->repeat = state->y = 4; \
|
context->repeat = state->y = 4; \
|
||||||
context->interlace = 2; \
|
context->interlace = 2; \
|
||||||
|
@ -57,10 +55,8 @@
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t bytes)
|
ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
UINT8 *p;
|
UINT8 *p;
|
||||||
UINT8 *out;
|
UINT8 *out;
|
||||||
int c, i;
|
int c, i;
|
||||||
|
@ -70,7 +66,6 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
UINT8 *ptr = buffer;
|
UINT8 *ptr = buffer;
|
||||||
|
|
||||||
if (!state->state) {
|
if (!state->state) {
|
||||||
|
|
||||||
/* Initialise state */
|
/* Initialise state */
|
||||||
if (context->bits < 0 || context->bits > 12) {
|
if (context->bits < 0 || context->bits > 12) {
|
||||||
state->errcode = IMAGING_CODEC_CONFIG;
|
state->errcode = IMAGING_CODEC_CONFIG;
|
||||||
|
@ -97,9 +92,7 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
out = im->image8[state->y + state->yoff] + state->xoff + state->x;
|
out = im->image8[state->y + state->yoff] + state->xoff + state->x;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (state->state == 1) {
|
if (state->state == 1) {
|
||||||
|
|
||||||
/* First free entry in table */
|
/* First free entry in table */
|
||||||
context->next = context->clear + 2;
|
context->next = context->clear + 2;
|
||||||
|
|
||||||
|
@ -115,7 +108,6 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->bufferindex < GIFBUFFER) {
|
if (context->bufferindex < GIFBUFFER) {
|
||||||
|
|
||||||
/* Return whole buffer in one chunk */
|
/* Return whole buffer in one chunk */
|
||||||
i = GIFBUFFER - context->bufferindex;
|
i = GIFBUFFER - context->bufferindex;
|
||||||
p = &context->buffer[context->bufferindex];
|
p = &context->buffer[context->bufferindex];
|
||||||
|
@ -123,15 +115,13 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
context->bufferindex = GIFBUFFER;
|
context->bufferindex = GIFBUFFER;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Get current symbol */
|
/* Get current symbol */
|
||||||
|
|
||||||
while (context->bitcount < context->codesize) {
|
while (context->bitcount < context->codesize) {
|
||||||
|
|
||||||
if (context->blocksize > 0) {
|
if (context->blocksize > 0) {
|
||||||
|
|
||||||
/* Read next byte */
|
/* Read next byte */
|
||||||
c = *ptr++; bytes--;
|
c = *ptr++;
|
||||||
|
bytes--;
|
||||||
|
|
||||||
context->blocksize--;
|
context->blocksize--;
|
||||||
|
|
||||||
|
@ -140,7 +130,6 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
context->bitcount += 8;
|
context->bitcount += 8;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* New GIF block */
|
/* New GIF block */
|
||||||
|
|
||||||
/* We don't start decoding unless we have a full block */
|
/* We don't start decoding unless we have a full block */
|
||||||
|
@ -154,8 +143,8 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
|
|
||||||
context->blocksize = c;
|
context->blocksize = c;
|
||||||
|
|
||||||
ptr++; bytes--;
|
ptr++;
|
||||||
|
bytes--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +174,6 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
p = &context->lastdata;
|
p = &context->lastdata;
|
||||||
|
|
||||||
if (state->state == 2) {
|
if (state->state == 2) {
|
||||||
|
|
||||||
/* First valid symbol after clear; use as is */
|
/* First valid symbol after clear; use as is */
|
||||||
if (c > context->clear) {
|
if (c > context->clear) {
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
|
@ -196,7 +184,6 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
state->state = 3;
|
state->state = 3;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
thiscode = c;
|
thiscode = c;
|
||||||
|
|
||||||
if (c > context->next) {
|
if (c > context->next) {
|
||||||
|
@ -205,7 +192,6 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == context->next) {
|
if (c == context->next) {
|
||||||
|
|
||||||
/* c == next is allowed. not sure why. */
|
/* c == next is allowed. not sure why. */
|
||||||
|
|
||||||
if (context->bufferindex <= 0) {
|
if (context->bufferindex <= 0) {
|
||||||
|
@ -213,15 +199,12 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->buffer[--context->bufferindex] =
|
context->buffer[--context->bufferindex] = context->lastdata;
|
||||||
context->lastdata;
|
|
||||||
|
|
||||||
c = context->lastcode;
|
c = context->lastcode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (c >= context->clear) {
|
while (c >= context->clear) {
|
||||||
|
|
||||||
/* Copy data string to buffer (beginning from right) */
|
/* Copy data string to buffer (beginning from right) */
|
||||||
|
|
||||||
if (context->bufferindex <= 0 || c >= GIFTABLE) {
|
if (context->bufferindex <= 0 || c >= GIFTABLE) {
|
||||||
|
@ -229,8 +212,7 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->buffer[--context->bufferindex] =
|
context->buffer[--context->bufferindex] = context->data[c];
|
||||||
context->data[c];
|
|
||||||
|
|
||||||
c = context->link[c];
|
c = context->link[c];
|
||||||
}
|
}
|
||||||
|
@ -238,7 +220,6 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
context->lastdata = c;
|
context->lastdata = c;
|
||||||
|
|
||||||
if (context->next < GIFTABLE) {
|
if (context->next < GIFTABLE) {
|
||||||
|
|
||||||
/* We'll only add this symbol if we have room
|
/* We'll only add this symbol if we have room
|
||||||
for it (take advise, Netscape!) */
|
for it (take advise, Netscape!) */
|
||||||
context->data[context->next] = c;
|
context->data[context->next] = c;
|
||||||
|
@ -246,18 +227,15 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
|
||||||
|
|
||||||
if (context->next == context->codemask &&
|
if (context->next == context->codemask &&
|
||||||
context->codesize < GIFBITS) {
|
context->codesize < GIFBITS) {
|
||||||
|
|
||||||
/* Expand code size */
|
/* Expand code size */
|
||||||
context->codesize++;
|
context->codesize++;
|
||||||
context->codemask = (1 << context->codesize) - 1;
|
context->codemask = (1 << context->codesize) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->next++;
|
context->next++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context->lastcode = thiscode;
|
context->lastcode = thiscode;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,7 @@ enum { INIT, ENCODE, ENCODE_EOF, FLUSH, EXIT };
|
||||||
necessary. */
|
necessary. */
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
emit(GIFENCODERSTATE *context, int byte)
|
emit(GIFENCODERSTATE *context, int byte) {
|
||||||
{
|
|
||||||
/* write a byte to the output buffer */
|
/* write a byte to the output buffer */
|
||||||
|
|
||||||
if (!context->block || context->block->size == 255) {
|
if (!context->block || context->block->size == 255) {
|
||||||
|
@ -74,7 +73,6 @@ emit(GIFENCODERSTATE *context, int byte)
|
||||||
block->next = NULL;
|
block->next = NULL;
|
||||||
|
|
||||||
context->block = block;
|
context->block = block;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write new byte to block */
|
/* write new byte to block */
|
||||||
|
@ -86,7 +84,8 @@ emit(GIFENCODERSTATE *context, int byte)
|
||||||
/* write a code word to the current block. this is a macro to make
|
/* write a code word to the current block. this is a macro to make
|
||||||
sure it's inlined on all platforms */
|
sure it's inlined on all platforms */
|
||||||
|
|
||||||
#define EMIT(code) {\
|
#define EMIT(code) \
|
||||||
|
{ \
|
||||||
context->bitbuffer |= ((INT32)(code)) << context->bitcount; \
|
context->bitbuffer |= ((INT32)(code)) << context->bitcount; \
|
||||||
context->bitcount += 9; \
|
context->bitcount += 9; \
|
||||||
while (context->bitcount >= 8) { \
|
while (context->bitcount >= 8) { \
|
||||||
|
@ -104,7 +103,8 @@ emit(GIFENCODERSTATE *context, int byte)
|
||||||
long stretches of identical pixels. but remember: if you want
|
long stretches of identical pixels. but remember: if you want
|
||||||
really good compression, use another file format. */
|
really good compression, use another file format. */
|
||||||
|
|
||||||
#define EMIT_RUN(label) {\
|
#define EMIT_RUN(label) \
|
||||||
|
{ \
|
||||||
label: \
|
label: \
|
||||||
while (context->count > 0) { \
|
while (context->count > 0) { \
|
||||||
int run = 2; \
|
int run = 2; \
|
||||||
|
@ -138,8 +138,7 @@ label:\
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
int this;
|
int this;
|
||||||
|
|
||||||
|
@ -147,7 +146,6 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
GIFENCODERSTATE *context = (GIFENCODERSTATE *)state->context;
|
GIFENCODERSTATE *context = (GIFENCODERSTATE *)state->context;
|
||||||
|
|
||||||
if (!state->state) {
|
if (!state->state) {
|
||||||
|
|
||||||
/* place a clear code in the output buffer */
|
/* place a clear code in the output buffer */
|
||||||
context->bitbuffer = CLEAR_CODE;
|
context->bitbuffer = CLEAR_CODE;
|
||||||
context->bitcount = 9;
|
context->bitcount = 9;
|
||||||
|
@ -167,22 +165,17 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
if (state->xsize <= 0 || state->ysize <= 0) {
|
if (state->xsize <= 0 || state->ysize <= 0) {
|
||||||
state->state = ENCODE_EOF;
|
state->state = ENCODE_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
for (;;)
|
for (;;) switch (state->state) {
|
||||||
|
|
||||||
switch (state->state) {
|
|
||||||
|
|
||||||
case INIT:
|
case INIT:
|
||||||
case ENCODE:
|
case ENCODE:
|
||||||
|
|
||||||
/* identify and store a run of pixels */
|
/* identify and store a run of pixels */
|
||||||
|
|
||||||
if (state->x == 0 || state->x >= state->xsize) {
|
if (state->x == 0 || state->x >= state->xsize) {
|
||||||
|
|
||||||
if (!context->interlace && state->y >= state->ysize) {
|
if (!context->interlace && state->y >= state->ysize) {
|
||||||
state->state = ENCODE_EOF;
|
state->state = ENCODE_EOF;
|
||||||
break;
|
break;
|
||||||
|
@ -197,8 +190,8 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
state->shuffle(
|
state->shuffle(
|
||||||
state->buffer,
|
state->buffer,
|
||||||
(UINT8 *)im->image[state->y + state->yoff] +
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
state->xoff * im->pixelsize, state->xsize
|
state->xoff * im->pixelsize,
|
||||||
);
|
state->xsize);
|
||||||
|
|
||||||
state->x = 0;
|
state->x = 0;
|
||||||
|
|
||||||
|
@ -231,7 +224,6 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
/* just make sure we don't loop forever */
|
/* just make sure we don't loop forever */
|
||||||
context->interlace = 0;
|
context->interlace = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/* Potential special case for xsize==1 */
|
/* Potential special case for xsize==1 */
|
||||||
if (state->x < state->xsize) {
|
if (state->x < state->xsize) {
|
||||||
|
@ -250,7 +242,6 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case ENCODE_EOF:
|
case ENCODE_EOF:
|
||||||
|
|
||||||
/* write the final run */
|
/* write the final run */
|
||||||
|
@ -292,12 +283,10 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
case FLUSH:
|
case FLUSH:
|
||||||
|
|
||||||
while (context->flush) {
|
while (context->flush) {
|
||||||
|
|
||||||
/* get a block from the flush queue */
|
/* get a block from the flush queue */
|
||||||
block = context->flush;
|
block = context->flush;
|
||||||
|
|
||||||
if (block->size > 0) {
|
if (block->size > 0) {
|
||||||
|
|
||||||
/* make sure it fits into the output buffer */
|
/* make sure it fits into the output buffer */
|
||||||
if (bytes < block->size + 1) {
|
if (bytes < block->size + 1) {
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
|
@ -308,7 +297,6 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
|
|
||||||
ptr += block->size + 1;
|
ptr += block->size + 1;
|
||||||
bytes -= block->size + 1;
|
bytes -= block->size + 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context->flush = block->next;
|
context->flush = block->next;
|
||||||
|
@ -317,7 +305,6 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
free(context->free);
|
free(context->free);
|
||||||
}
|
}
|
||||||
context->free = block;
|
context->free = block;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->state == EXIT) {
|
if (state->state == EXIT) {
|
||||||
|
|
|
@ -13,23 +13,22 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#define HEX(v) ((v >= '0' && v <= '9') ? v - '0' :\
|
#define HEX(v) \
|
||||||
(v >= 'a' && v <= 'f') ? v - 'a' + 10 :\
|
((v >= '0' && v <= '9') ? v - '0' \
|
||||||
(v >= 'A' && v <= 'F') ? v - 'A' + 10 : -1)
|
: (v >= 'a' && v <= 'f') ? v - 'a' + 10 \
|
||||||
|
: (v >= 'A' && v <= 'F') ? v - 'A' + 10 \
|
||||||
|
: -1)
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
int a, b;
|
int a, b;
|
||||||
|
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (bytes < 2) {
|
if (bytes < 2) {
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
}
|
}
|
||||||
|
@ -38,22 +37,19 @@ ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
b = HEX(ptr[1]);
|
b = HEX(ptr[1]);
|
||||||
|
|
||||||
if (a < 0 || b < 0) {
|
if (a < 0 || b < 0) {
|
||||||
|
|
||||||
ptr++;
|
ptr++;
|
||||||
bytes--;
|
bytes--;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
bytes -= 2;
|
bytes -= 2;
|
||||||
|
|
||||||
state->buffer[state->x] = (a << 4) + b;
|
state->buffer[state->x] = (a << 4) + b;
|
||||||
|
|
||||||
if (++state->x >= state->bytes) {
|
if (++state->x >= state->bytes) {
|
||||||
|
|
||||||
/* Got a full line, unpack it */
|
/* Got a full line, unpack it */
|
||||||
state->shuffle((UINT8*) im->image[state->y], state->buffer,
|
state->shuffle(
|
||||||
state->xsize);
|
(UINT8 *)im->image[state->y], state->buffer, state->xsize);
|
||||||
|
|
||||||
state->x = 0;
|
state->x = 0;
|
||||||
|
|
||||||
|
@ -62,7 +58,6 @@ ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,8 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
/* HISTOGRAM */
|
/* HISTOGRAM */
|
||||||
/* --------------------------------------------------------------------
|
/* --------------------------------------------------------------------
|
||||||
* Take a histogram of an image. Returns a histogram object containing
|
* Take a histogram of an image. Returns a histogram object containing
|
||||||
|
@ -27,8 +25,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingHistogramDelete(ImagingHistogram h)
|
ImagingHistogramDelete(ImagingHistogram h) {
|
||||||
{
|
|
||||||
if (h) {
|
if (h) {
|
||||||
if (h->histogram) {
|
if (h->histogram) {
|
||||||
free(h->histogram);
|
free(h->histogram);
|
||||||
|
@ -38,8 +35,7 @@ ImagingHistogramDelete(ImagingHistogram h)
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingHistogram
|
ImagingHistogram
|
||||||
ImagingHistogramNew(Imaging im)
|
ImagingHistogramNew(Imaging im) {
|
||||||
{
|
|
||||||
ImagingHistogram h;
|
ImagingHistogram h;
|
||||||
|
|
||||||
/* Create histogram descriptor */
|
/* Create histogram descriptor */
|
||||||
|
@ -61,8 +57,7 @@ ImagingHistogramNew(Imaging im)
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingHistogram
|
ImagingHistogram
|
||||||
ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax)
|
ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int x, y, i;
|
int x, y, i;
|
||||||
ImagingHistogram h;
|
ImagingHistogram h;
|
||||||
|
|
|
@ -37,18 +37,25 @@ struct ImagingDIBInstance {
|
||||||
|
|
||||||
typedef struct ImagingDIBInstance *ImagingDIB;
|
typedef struct ImagingDIBInstance *ImagingDIB;
|
||||||
|
|
||||||
extern char* ImagingGetModeDIB(int size_out[2]);
|
extern char *
|
||||||
|
ImagingGetModeDIB(int size_out[2]);
|
||||||
|
|
||||||
extern ImagingDIB ImagingNewDIB(const char *mode, int xsize, int ysize);
|
extern ImagingDIB
|
||||||
|
ImagingNewDIB(const char *mode, int xsize, int ysize);
|
||||||
|
|
||||||
extern void ImagingDeleteDIB(ImagingDIB im);
|
extern void
|
||||||
|
ImagingDeleteDIB(ImagingDIB im);
|
||||||
|
|
||||||
extern void ImagingDrawDIB(ImagingDIB dib, void *dc, int dst[4], int src[4]);
|
extern void
|
||||||
extern void ImagingExposeDIB(ImagingDIB dib, void *dc);
|
ImagingDrawDIB(ImagingDIB dib, void *dc, int dst[4], int src[4]);
|
||||||
|
extern void
|
||||||
|
ImagingExposeDIB(ImagingDIB dib, void *dc);
|
||||||
|
|
||||||
extern int ImagingQueryPaletteDIB(ImagingDIB dib, void *dc);
|
extern int
|
||||||
|
ImagingQueryPaletteDIB(ImagingDIB dib, void *dc);
|
||||||
|
|
||||||
extern void ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]);
|
extern void
|
||||||
|
ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
||||||
/* Workaround issue #2479 */
|
/* Workaround issue #2479 */
|
||||||
#if PY_VERSION_HEX < 0x03070000 && defined(PySlice_GetIndicesEx) && !defined(PYPY_VERSION)
|
#if PY_VERSION_HEX < 0x03070000 && defined(PySlice_GetIndicesEx) && \
|
||||||
|
!defined(PYPY_VERSION)
|
||||||
#undef PySlice_GetIndicesEx
|
#undef PySlice_GetIndicesEx
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -80,7 +81,5 @@ typedef signed __int64 int64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define GCC_VERSION (__GNUC__ * 10000 \
|
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||||
+ __GNUC_MINOR__ * 100 \
|
|
||||||
+ __GNUC_PATCHLEVEL__)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,20 +10,16 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "ImPlatform.h"
|
#include "ImPlatform.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
#define M_PI 3.1415926535897932384626433832795
|
#define M_PI 3.1415926535897932384626433832795
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -73,7 +69,8 @@ typedef struct ImagingPaletteInstance* ImagingPalette;
|
||||||
#define IMAGING_TYPE_FLOAT32 2
|
#define IMAGING_TYPE_FLOAT32 2
|
||||||
#define IMAGING_TYPE_SPECIAL 3 /* check mode for details */
|
#define IMAGING_TYPE_SPECIAL 3 /* check mode for details */
|
||||||
|
|
||||||
#define IMAGING_MODE_LENGTH 6+1 /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "BGR;xy") */
|
#define IMAGING_MODE_LENGTH \
|
||||||
|
6 + 1 /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "BGR;xy") */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
@ -81,9 +78,9 @@ typedef struct {
|
||||||
} ImagingMemoryBlock;
|
} ImagingMemoryBlock;
|
||||||
|
|
||||||
struct ImagingMemoryInstance {
|
struct ImagingMemoryInstance {
|
||||||
|
|
||||||
/* Format */
|
/* Format */
|
||||||
char mode[IMAGING_MODE_LENGTH]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "BGR;xy") */
|
char mode[IMAGING_MODE_LENGTH]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK",
|
||||||
|
"YCbCr", "BGR;xy") */
|
||||||
int type; /* Data type (IMAGING_TYPE_*) */
|
int type; /* Data type (IMAGING_TYPE_*) */
|
||||||
int depth; /* Depth (ignored in this version) */
|
int depth; /* Depth (ignored in this version) */
|
||||||
int bands; /* Number of bands (1, 2, 3, or 4) */
|
int bands; /* Number of bands (1, 2, 3, or 4) */
|
||||||
|
@ -109,7 +106,6 @@ struct ImagingMemoryInstance {
|
||||||
void (*destroy)(Imaging im);
|
void (*destroy)(Imaging im);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define IMAGING_PIXEL_1(im, x, y) ((im)->image8[(y)][(x)])
|
#define IMAGING_PIXEL_1(im, x, y) ((im)->image8[(y)][(x)])
|
||||||
#define IMAGING_PIXEL_L(im, x, y) ((im)->image8[(y)][(x)])
|
#define IMAGING_PIXEL_L(im, x, y) ((im)->image8[(y)][(x)])
|
||||||
#define IMAGING_PIXEL_LA(im, x, y) ((im)->image[(y)][(x)*4])
|
#define IMAGING_PIXEL_LA(im, x, y) ((im)->image[(y)][(x)*4])
|
||||||
|
@ -134,19 +130,15 @@ struct ImagingAccessInstance {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImagingHistogramInstance {
|
struct ImagingHistogramInstance {
|
||||||
|
|
||||||
/* Format */
|
/* Format */
|
||||||
char mode[IMAGING_MODE_LENGTH]; /* Band names (of corresponding source image) */
|
char mode[IMAGING_MODE_LENGTH]; /* Band names (of corresponding source image) */
|
||||||
int bands; /* Number of bands (1, 3, or 4) */
|
int bands; /* Number of bands (1, 3, or 4) */
|
||||||
|
|
||||||
/* Data */
|
/* Data */
|
||||||
long *histogram; /* Histogram (bands*256 longs) */
|
long *histogram; /* Histogram (bands*256 longs) */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ImagingPaletteInstance {
|
struct ImagingPaletteInstance {
|
||||||
|
|
||||||
/* Format */
|
/* Format */
|
||||||
char mode[IMAGING_MODE_LENGTH]; /* Band names */
|
char mode[IMAGING_MODE_LENGTH]; /* Band names */
|
||||||
|
|
||||||
|
@ -155,7 +147,6 @@ struct ImagingPaletteInstance {
|
||||||
|
|
||||||
INT16 *cache; /* Palette cache (used for predefined palettes) */
|
INT16 *cache; /* Palette cache (used for predefined palettes) */
|
||||||
int keep_cache; /* This palette will be reused; keep cache */
|
int keep_cache; /* This palette will be reused; keep cache */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ImagingMemoryArena {
|
typedef struct ImagingMemoryArena {
|
||||||
|
@ -167,72 +158,98 @@ typedef struct ImagingMemoryArena {
|
||||||
int stats_new_count; /* Number of new allocated images */
|
int stats_new_count; /* Number of new allocated images */
|
||||||
int stats_allocated_blocks; /* Number of allocated blocks */
|
int stats_allocated_blocks; /* Number of allocated blocks */
|
||||||
int stats_reused_blocks; /* Number of blocks which were retrieved from a pool */
|
int stats_reused_blocks; /* Number of blocks which were retrieved from a pool */
|
||||||
int stats_reallocated_blocks; /* Number of blocks which were actually reallocated after retrieving */
|
int stats_reallocated_blocks; /* Number of blocks which were actually reallocated
|
||||||
|
after retrieving */
|
||||||
int stats_freed_blocks; /* Number of freed blocks */
|
int stats_freed_blocks; /* Number of freed blocks */
|
||||||
} * ImagingMemoryArena;
|
} * ImagingMemoryArena;
|
||||||
|
|
||||||
|
|
||||||
/* Objects */
|
/* Objects */
|
||||||
/* ------- */
|
/* ------- */
|
||||||
|
|
||||||
extern struct ImagingMemoryArena ImagingDefaultArena;
|
extern struct ImagingMemoryArena ImagingDefaultArena;
|
||||||
extern int ImagingMemorySetBlocksMax(ImagingMemoryArena arena, int blocks_max);
|
extern int
|
||||||
extern void ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size);
|
ImagingMemorySetBlocksMax(ImagingMemoryArena arena, int blocks_max);
|
||||||
|
extern void
|
||||||
|
ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size);
|
||||||
|
|
||||||
extern Imaging ImagingNew(const char* mode, int xsize, int ysize);
|
extern Imaging
|
||||||
extern Imaging ImagingNewDirty(const char* mode, int xsize, int ysize);
|
ImagingNew(const char *mode, int xsize, int ysize);
|
||||||
extern Imaging ImagingNew2Dirty(const char* mode, Imaging imOut, Imaging imIn);
|
extern Imaging
|
||||||
extern void ImagingDelete(Imaging im);
|
ImagingNewDirty(const char *mode, int xsize, int ysize);
|
||||||
|
extern Imaging
|
||||||
|
ImagingNew2Dirty(const char *mode, Imaging imOut, Imaging imIn);
|
||||||
|
extern void
|
||||||
|
ImagingDelete(Imaging im);
|
||||||
|
|
||||||
extern Imaging ImagingNewBlock(const char* mode, int xsize, int ysize);
|
extern Imaging
|
||||||
|
ImagingNewBlock(const char *mode, int xsize, int ysize);
|
||||||
|
|
||||||
extern Imaging ImagingNewPrologue(const char *mode,
|
extern Imaging
|
||||||
int xsize, int ysize);
|
ImagingNewPrologue(const char *mode, int xsize, int ysize);
|
||||||
extern Imaging ImagingNewPrologueSubtype(const char *mode,
|
extern Imaging
|
||||||
int xsize, int ysize,
|
ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int structure_size);
|
||||||
int structure_size);
|
|
||||||
|
|
||||||
extern void ImagingCopyPalette(Imaging destination, Imaging source);
|
extern void
|
||||||
|
ImagingCopyPalette(Imaging destination, Imaging source);
|
||||||
|
|
||||||
extern void ImagingHistogramDelete(ImagingHistogram histogram);
|
extern void
|
||||||
|
ImagingHistogramDelete(ImagingHistogram histogram);
|
||||||
|
|
||||||
extern void ImagingAccessInit(void);
|
extern void
|
||||||
extern ImagingAccess ImagingAccessNew(Imaging im);
|
ImagingAccessInit(void);
|
||||||
extern void _ImagingAccessDelete(Imaging im, ImagingAccess access);
|
extern ImagingAccess
|
||||||
|
ImagingAccessNew(Imaging im);
|
||||||
|
extern void
|
||||||
|
_ImagingAccessDelete(Imaging im, ImagingAccess access);
|
||||||
#define ImagingAccessDelete(im, access) /* nop, for now */
|
#define ImagingAccessDelete(im, access) /* nop, for now */
|
||||||
|
|
||||||
extern ImagingPalette ImagingPaletteNew(const char *mode);
|
extern ImagingPalette
|
||||||
extern ImagingPalette ImagingPaletteNewBrowser(void);
|
ImagingPaletteNew(const char *mode);
|
||||||
extern ImagingPalette ImagingPaletteDuplicate(ImagingPalette palette);
|
extern ImagingPalette
|
||||||
extern void ImagingPaletteDelete(ImagingPalette palette);
|
ImagingPaletteNewBrowser(void);
|
||||||
|
extern ImagingPalette
|
||||||
|
ImagingPaletteDuplicate(ImagingPalette palette);
|
||||||
|
extern void
|
||||||
|
ImagingPaletteDelete(ImagingPalette palette);
|
||||||
|
|
||||||
extern int ImagingPaletteCachePrepare(ImagingPalette palette);
|
extern int
|
||||||
extern void ImagingPaletteCacheUpdate(ImagingPalette palette,
|
ImagingPaletteCachePrepare(ImagingPalette palette);
|
||||||
int r, int g, int b);
|
extern void
|
||||||
extern void ImagingPaletteCacheDelete(ImagingPalette palette);
|
ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b);
|
||||||
|
extern void
|
||||||
|
ImagingPaletteCacheDelete(ImagingPalette palette);
|
||||||
|
|
||||||
#define ImagingPaletteCache(p, r, g, b) \
|
#define ImagingPaletteCache(p, r, g, b) \
|
||||||
p->cache[(r >> 2) + (g >> 2) * 64 + (b >> 2) * 64 * 64]
|
p->cache[(r >> 2) + (g >> 2) * 64 + (b >> 2) * 64 * 64]
|
||||||
|
|
||||||
extern Imaging ImagingQuantize(Imaging im, int colours, int mode, int kmeans);
|
extern Imaging
|
||||||
|
ImagingQuantize(Imaging im, int colours, int mode, int kmeans);
|
||||||
|
|
||||||
/* Threading */
|
/* Threading */
|
||||||
/* --------- */
|
/* --------- */
|
||||||
|
|
||||||
typedef void *ImagingSectionCookie;
|
typedef void *ImagingSectionCookie;
|
||||||
|
|
||||||
extern void ImagingSectionEnter(ImagingSectionCookie* cookie);
|
extern void
|
||||||
extern void ImagingSectionLeave(ImagingSectionCookie* cookie);
|
ImagingSectionEnter(ImagingSectionCookie *cookie);
|
||||||
|
extern void
|
||||||
|
ImagingSectionLeave(ImagingSectionCookie *cookie);
|
||||||
|
|
||||||
/* Exceptions */
|
/* Exceptions */
|
||||||
/* ---------- */
|
/* ---------- */
|
||||||
|
|
||||||
extern void* ImagingError_OSError(void);
|
extern void *
|
||||||
extern void* ImagingError_MemoryError(void);
|
ImagingError_OSError(void);
|
||||||
extern void* ImagingError_ModeError(void); /* maps to ValueError by default */
|
extern void *
|
||||||
extern void* ImagingError_Mismatch(void); /* maps to ValueError by default */
|
ImagingError_MemoryError(void);
|
||||||
extern void* ImagingError_ValueError(const char* message);
|
extern void *
|
||||||
extern void ImagingError_Clear(void);
|
ImagingError_ModeError(void); /* maps to ValueError by default */
|
||||||
|
extern void *
|
||||||
|
ImagingError_Mismatch(void); /* maps to ValueError by default */
|
||||||
|
extern void *
|
||||||
|
ImagingError_ValueError(const char *message);
|
||||||
|
extern void
|
||||||
|
ImagingError_Clear(void);
|
||||||
|
|
||||||
/* Transform callbacks */
|
/* Transform callbacks */
|
||||||
/* ------------------- */
|
/* ------------------- */
|
||||||
|
@ -242,7 +259,6 @@ extern void ImagingError_Clear(void);
|
||||||
#define IMAGING_TRANSFORM_PERSPECTIVE 2
|
#define IMAGING_TRANSFORM_PERSPECTIVE 2
|
||||||
#define IMAGING_TRANSFORM_QUAD 3
|
#define IMAGING_TRANSFORM_QUAD 3
|
||||||
|
|
||||||
|
|
||||||
/* standard filters */
|
/* standard filters */
|
||||||
#define IMAGING_TRANSFORM_NEAREST 0
|
#define IMAGING_TRANSFORM_NEAREST 0
|
||||||
#define IMAGING_TRANSFORM_BOX 4
|
#define IMAGING_TRANSFORM_BOX 4
|
||||||
|
@ -251,249 +267,391 @@ extern void ImagingError_Clear(void);
|
||||||
#define IMAGING_TRANSFORM_BICUBIC 3
|
#define IMAGING_TRANSFORM_BICUBIC 3
|
||||||
#define IMAGING_TRANSFORM_LANCZOS 1
|
#define IMAGING_TRANSFORM_LANCZOS 1
|
||||||
|
|
||||||
typedef int (*ImagingTransformMap)(double* X, double* Y,
|
typedef int (*ImagingTransformMap)(double *X, double *Y, int x, int y, void *data);
|
||||||
int x, int y, void* data);
|
typedef int (*ImagingTransformFilter)(void *out, Imaging im, double x, double y);
|
||||||
typedef int (*ImagingTransformFilter)(void* out, Imaging im,
|
|
||||||
double x, double y);
|
|
||||||
|
|
||||||
/* Image Manipulation Methods */
|
/* Image Manipulation Methods */
|
||||||
/* -------------------------- */
|
/* -------------------------- */
|
||||||
|
|
||||||
extern Imaging ImagingAlphaComposite(Imaging imIn1, Imaging imIn2);
|
extern Imaging
|
||||||
extern Imaging ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha);
|
ImagingAlphaComposite(Imaging imIn1, Imaging imIn2);
|
||||||
extern Imaging ImagingCopy(Imaging im);
|
extern Imaging
|
||||||
extern Imaging ImagingConvert(Imaging im, const char* mode, ImagingPalette palette, int dither);
|
ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha);
|
||||||
extern Imaging ImagingConvertInPlace(Imaging im, const char* mode);
|
extern Imaging
|
||||||
extern Imaging ImagingConvertMatrix(Imaging im, const char *mode, float m[]);
|
ImagingCopy(Imaging im);
|
||||||
extern Imaging ImagingConvertTransparent(Imaging im, const char *mode, int r, int g, int b);
|
extern Imaging
|
||||||
extern Imaging ImagingCrop(Imaging im, int x0, int y0, int x1, int y1);
|
ImagingConvert(Imaging im, const char *mode, ImagingPalette palette, int dither);
|
||||||
extern Imaging ImagingExpand(Imaging im, int x, int y, int mode);
|
extern Imaging
|
||||||
extern Imaging ImagingFill(Imaging im, const void* ink);
|
ImagingConvertInPlace(Imaging im, const char *mode);
|
||||||
extern int ImagingFill2(
|
extern Imaging
|
||||||
Imaging into, const void* ink, Imaging mask,
|
ImagingConvertMatrix(Imaging im, const char *mode, float m[]);
|
||||||
int x0, int y0, int x1, int y1);
|
extern Imaging
|
||||||
extern Imaging ImagingFillBand(Imaging im, int band, int color);
|
ImagingConvertTransparent(Imaging im, const char *mode, int r, int g, int b);
|
||||||
extern Imaging ImagingFillLinearGradient(const char* mode);
|
extern Imaging
|
||||||
extern Imaging ImagingFillRadialGradient(const char* mode);
|
ImagingCrop(Imaging im, int x0, int y0, int x1, int y1);
|
||||||
extern Imaging ImagingFilter(
|
extern Imaging
|
||||||
Imaging im, int xsize, int ysize, const FLOAT32* kernel,
|
ImagingExpand(Imaging im, int x, int y, int mode);
|
||||||
FLOAT32 offset);
|
extern Imaging
|
||||||
extern Imaging ImagingFlipLeftRight(Imaging imOut, Imaging imIn);
|
ImagingFill(Imaging im, const void *ink);
|
||||||
extern Imaging ImagingFlipTopBottom(Imaging imOut, Imaging imIn);
|
extern int
|
||||||
extern Imaging ImagingGaussianBlur(Imaging imOut, Imaging imIn, float radius,
|
ImagingFill2(
|
||||||
int passes);
|
Imaging into, const void *ink, Imaging mask, int x0, int y0, int x1, int y1);
|
||||||
extern Imaging ImagingGetBand(Imaging im, int band);
|
extern Imaging
|
||||||
extern Imaging ImagingMerge(const char* mode, Imaging bands[4]);
|
ImagingFillBand(Imaging im, int band, int color);
|
||||||
extern int ImagingSplit(Imaging im, Imaging bands[4]);
|
extern Imaging
|
||||||
extern int ImagingGetBBox(Imaging im, int bbox[4]);
|
ImagingFillLinearGradient(const char *mode);
|
||||||
typedef struct { int x, y; INT32 count; INT32 pixel; } ImagingColorItem;
|
extern Imaging
|
||||||
extern ImagingColorItem* ImagingGetColors(Imaging im, int maxcolors,
|
ImagingFillRadialGradient(const char *mode);
|
||||||
int *colors);
|
extern Imaging
|
||||||
extern int ImagingGetExtrema(Imaging im, void *extrema);
|
ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 offset);
|
||||||
extern int ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj);
|
extern Imaging
|
||||||
extern ImagingHistogram ImagingGetHistogram(
|
ImagingFlipLeftRight(Imaging imOut, Imaging imIn);
|
||||||
Imaging im, Imaging mask, void *extrema);
|
extern Imaging
|
||||||
extern Imaging ImagingModeFilter(Imaging im, int size);
|
ImagingFlipTopBottom(Imaging imOut, Imaging imIn);
|
||||||
extern Imaging ImagingNegative(Imaging im);
|
extern Imaging
|
||||||
extern Imaging ImagingOffset(Imaging im, int xoffset, int yoffset);
|
ImagingGaussianBlur(Imaging imOut, Imaging imIn, float radius, int passes);
|
||||||
extern int ImagingPaste(
|
extern Imaging
|
||||||
Imaging into, Imaging im, Imaging mask,
|
ImagingGetBand(Imaging im, int band);
|
||||||
int x0, int y0, int x1, int y1);
|
extern Imaging
|
||||||
extern Imaging ImagingPoint(
|
ImagingMerge(const char *mode, Imaging bands[4]);
|
||||||
Imaging im, const char* tablemode, const void* table);
|
extern int
|
||||||
extern Imaging ImagingPointTransform(
|
ImagingSplit(Imaging im, Imaging bands[4]);
|
||||||
Imaging imIn, double scale, double offset);
|
extern int
|
||||||
extern Imaging ImagingPutBand(Imaging im, Imaging imIn, int band);
|
ImagingGetBBox(Imaging im, int bbox[4]);
|
||||||
extern Imaging ImagingRankFilter(Imaging im, int size, int rank);
|
typedef struct {
|
||||||
extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn);
|
int x, y;
|
||||||
extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn);
|
INT32 count;
|
||||||
extern Imaging ImagingRotate270(Imaging imOut, Imaging imIn);
|
INT32 pixel;
|
||||||
extern Imaging ImagingTranspose(Imaging imOut, Imaging imIn);
|
} ImagingColorItem;
|
||||||
extern Imaging ImagingTransverse(Imaging imOut, Imaging imIn);
|
extern ImagingColorItem *
|
||||||
extern Imaging ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]);
|
ImagingGetColors(Imaging im, int maxcolors, int *colors);
|
||||||
extern Imaging ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]);
|
extern int
|
||||||
extern Imaging ImagingTransform(
|
ImagingGetExtrema(Imaging im, void *extrema);
|
||||||
Imaging imOut, Imaging imIn, int method, int x0, int y0, int x1, int y1,
|
extern int
|
||||||
double *a, int filter, int fill);
|
ImagingGetProjection(Imaging im, UINT8 *xproj, UINT8 *yproj);
|
||||||
extern Imaging ImagingUnsharpMask(
|
extern ImagingHistogram
|
||||||
Imaging imOut, Imaging im, float radius, int percent, int threshold);
|
ImagingGetHistogram(Imaging im, Imaging mask, void *extrema);
|
||||||
extern Imaging ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n);
|
extern Imaging
|
||||||
extern Imaging ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn,
|
ImagingModeFilter(Imaging im, int size);
|
||||||
int table_channels, int size1D, int size2D, int size3D, INT16* table);
|
extern Imaging
|
||||||
|
ImagingNegative(Imaging im);
|
||||||
|
extern Imaging
|
||||||
|
ImagingOffset(Imaging im, int xoffset, int yoffset);
|
||||||
|
extern int
|
||||||
|
ImagingPaste(Imaging into, Imaging im, Imaging mask, int x0, int y0, int x1, int y1);
|
||||||
|
extern Imaging
|
||||||
|
ImagingPoint(Imaging im, const char *tablemode, const void *table);
|
||||||
|
extern Imaging
|
||||||
|
ImagingPointTransform(Imaging imIn, double scale, double offset);
|
||||||
|
extern Imaging
|
||||||
|
ImagingPutBand(Imaging im, Imaging imIn, int band);
|
||||||
|
extern Imaging
|
||||||
|
ImagingRankFilter(Imaging im, int size, int rank);
|
||||||
|
extern Imaging
|
||||||
|
ImagingRotate90(Imaging imOut, Imaging imIn);
|
||||||
|
extern Imaging
|
||||||
|
ImagingRotate180(Imaging imOut, Imaging imIn);
|
||||||
|
extern Imaging
|
||||||
|
ImagingRotate270(Imaging imOut, Imaging imIn);
|
||||||
|
extern Imaging
|
||||||
|
ImagingTranspose(Imaging imOut, Imaging imIn);
|
||||||
|
extern Imaging
|
||||||
|
ImagingTransverse(Imaging imOut, Imaging imIn);
|
||||||
|
extern Imaging
|
||||||
|
ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]);
|
||||||
|
extern Imaging
|
||||||
|
ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]);
|
||||||
|
extern Imaging
|
||||||
|
ImagingTransform(
|
||||||
|
Imaging imOut,
|
||||||
|
Imaging imIn,
|
||||||
|
int method,
|
||||||
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
double *a,
|
||||||
|
int filter,
|
||||||
|
int fill);
|
||||||
|
extern Imaging
|
||||||
|
ImagingUnsharpMask(Imaging imOut, Imaging im, float radius, int percent, int threshold);
|
||||||
|
extern Imaging
|
||||||
|
ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n);
|
||||||
|
extern Imaging
|
||||||
|
ImagingColorLUT3D_linear(
|
||||||
|
Imaging imOut,
|
||||||
|
Imaging imIn,
|
||||||
|
int table_channels,
|
||||||
|
int size1D,
|
||||||
|
int size2D,
|
||||||
|
int size3D,
|
||||||
|
INT16 *table);
|
||||||
|
|
||||||
extern Imaging ImagingCopy2(Imaging imOut, Imaging imIn);
|
extern Imaging
|
||||||
extern Imaging ImagingConvert2(Imaging imOut, Imaging imIn);
|
ImagingCopy2(Imaging imOut, Imaging imIn);
|
||||||
|
extern Imaging
|
||||||
|
ImagingConvert2(Imaging imOut, Imaging imIn);
|
||||||
|
|
||||||
/* Channel operations */
|
/* Channel operations */
|
||||||
/* any mode, except "F" */
|
/* any mode, except "F" */
|
||||||
extern Imaging ImagingChopLighter(Imaging imIn1, Imaging imIn2);
|
extern Imaging
|
||||||
extern Imaging ImagingChopDarker(Imaging imIn1, Imaging imIn2);
|
ImagingChopLighter(Imaging imIn1, Imaging imIn2);
|
||||||
extern Imaging ImagingChopDifference(Imaging imIn1, Imaging imIn2);
|
extern Imaging
|
||||||
extern Imaging ImagingChopMultiply(Imaging imIn1, Imaging imIn2);
|
ImagingChopDarker(Imaging imIn1, Imaging imIn2);
|
||||||
extern Imaging ImagingChopScreen(Imaging imIn1, Imaging imIn2);
|
extern Imaging
|
||||||
extern Imaging ImagingChopAdd(
|
ImagingChopDifference(Imaging imIn1, Imaging imIn2);
|
||||||
Imaging imIn1, Imaging imIn2, float scale, int offset);
|
extern Imaging
|
||||||
extern Imaging ImagingChopSubtract(
|
ImagingChopMultiply(Imaging imIn1, Imaging imIn2);
|
||||||
Imaging imIn1, Imaging imIn2, float scale, int offset);
|
extern Imaging
|
||||||
extern Imaging ImagingChopAddModulo(Imaging imIn1, Imaging imIn2);
|
ImagingChopScreen(Imaging imIn1, Imaging imIn2);
|
||||||
extern Imaging ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2);
|
extern Imaging
|
||||||
extern Imaging ImagingChopSoftLight(Imaging imIn1, Imaging imIn2);
|
ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset);
|
||||||
extern Imaging ImagingChopHardLight(Imaging imIn1, Imaging imIn2);
|
extern Imaging
|
||||||
extern Imaging ImagingOverlay(Imaging imIn1, Imaging imIn2);
|
ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset);
|
||||||
|
extern Imaging
|
||||||
|
ImagingChopAddModulo(Imaging imIn1, Imaging imIn2);
|
||||||
|
extern Imaging
|
||||||
|
ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2);
|
||||||
|
extern Imaging
|
||||||
|
ImagingChopSoftLight(Imaging imIn1, Imaging imIn2);
|
||||||
|
extern Imaging
|
||||||
|
ImagingChopHardLight(Imaging imIn1, Imaging imIn2);
|
||||||
|
extern Imaging
|
||||||
|
ImagingOverlay(Imaging imIn1, Imaging imIn2);
|
||||||
|
|
||||||
/* "1" images only */
|
/* "1" images only */
|
||||||
extern Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2);
|
extern Imaging
|
||||||
extern Imaging ImagingChopOr(Imaging imIn1, Imaging imIn2);
|
ImagingChopAnd(Imaging imIn1, Imaging imIn2);
|
||||||
extern Imaging ImagingChopXor(Imaging imIn1, Imaging imIn2);
|
extern Imaging
|
||||||
|
ImagingChopOr(Imaging imIn1, Imaging imIn2);
|
||||||
|
extern Imaging
|
||||||
|
ImagingChopXor(Imaging imIn1, Imaging imIn2);
|
||||||
|
|
||||||
/* Graphics */
|
/* Graphics */
|
||||||
extern int ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1,
|
extern int
|
||||||
float start, float end, const void* ink, int width,
|
ImagingDrawArc(
|
||||||
|
Imaging im,
|
||||||
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink,
|
||||||
|
int width,
|
||||||
|
int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void *ink, int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawChord(
|
||||||
|
Imaging im,
|
||||||
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
|
int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawEllipse(
|
||||||
|
Imaging im,
|
||||||
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
const void *ink,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
|
int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void *ink, int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawWideLine(
|
||||||
|
Imaging im, int x0, int y0, int x1, int y1, const void *ink, int width, int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawPieslice(
|
||||||
|
Imaging im,
|
||||||
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
float start,
|
||||||
|
float end,
|
||||||
|
const void *ink,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
|
int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawPoint(Imaging im, int x, int y, const void *ink, int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawPolygon(Imaging im, int points, int *xy, const void *ink, int fill, int op);
|
||||||
|
extern int
|
||||||
|
ImagingDrawRectangle(
|
||||||
|
Imaging im,
|
||||||
|
int x0,
|
||||||
|
int y0,
|
||||||
|
int x1,
|
||||||
|
int y1,
|
||||||
|
const void *ink,
|
||||||
|
int fill,
|
||||||
|
int width,
|
||||||
int op);
|
int op);
|
||||||
extern int ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap,
|
|
||||||
const void* ink, int op);
|
|
||||||
extern int ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1,
|
|
||||||
float start, float end, const void* ink, int fill,
|
|
||||||
int width, int op);
|
|
||||||
extern int ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1,
|
|
||||||
const void* ink, int fill, int width, int op);
|
|
||||||
extern int ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1,
|
|
||||||
const void* ink, int op);
|
|
||||||
extern int ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
|
|
||||||
const void* ink, int width, int op);
|
|
||||||
extern int ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1,
|
|
||||||
float start, float end, const void* ink, int fill,
|
|
||||||
int width, int op);
|
|
||||||
extern int ImagingDrawPoint(Imaging im, int x, int y, const void* ink, int op);
|
|
||||||
extern int ImagingDrawPolygon(Imaging im, int points, int *xy,
|
|
||||||
const void* ink, int fill, int op);
|
|
||||||
extern int ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
|
|
||||||
const void* ink, int fill, int width, int op);
|
|
||||||
|
|
||||||
/* Level 2 graphics (WORK IN PROGRESS) */
|
/* Level 2 graphics (WORK IN PROGRESS) */
|
||||||
extern ImagingOutline ImagingOutlineNew(void);
|
extern ImagingOutline
|
||||||
extern void ImagingOutlineDelete(ImagingOutline outline);
|
ImagingOutlineNew(void);
|
||||||
|
extern void
|
||||||
|
ImagingOutlineDelete(ImagingOutline outline);
|
||||||
|
|
||||||
extern int ImagingDrawOutline(Imaging im, ImagingOutline outline,
|
extern int
|
||||||
const void* ink, int fill, int op);
|
ImagingDrawOutline(
|
||||||
|
Imaging im, ImagingOutline outline, const void *ink, int fill, int op);
|
||||||
|
|
||||||
extern int ImagingOutlineMove(ImagingOutline outline, float x, float y);
|
extern int
|
||||||
extern int ImagingOutlineLine(ImagingOutline outline, float x, float y);
|
ImagingOutlineMove(ImagingOutline outline, float x, float y);
|
||||||
extern int ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
|
extern int
|
||||||
float x2, float y2, float x3, float y3);
|
ImagingOutlineLine(ImagingOutline outline, float x, float y);
|
||||||
extern int ImagingOutlineTransform(ImagingOutline outline, double a[6]);
|
extern int
|
||||||
|
ImagingOutlineCurve(
|
||||||
|
ImagingOutline outline, float x1, float y1, float x2, float y2, float x3, float y3);
|
||||||
|
extern int
|
||||||
|
ImagingOutlineTransform(ImagingOutline outline, double a[6]);
|
||||||
|
|
||||||
extern int ImagingOutlineClose(ImagingOutline outline);
|
extern int
|
||||||
|
ImagingOutlineClose(ImagingOutline outline);
|
||||||
|
|
||||||
/* Special effects */
|
/* Special effects */
|
||||||
extern Imaging ImagingEffectSpread(Imaging imIn, int distance);
|
extern Imaging
|
||||||
extern Imaging ImagingEffectNoise(int xsize, int ysize, float sigma);
|
ImagingEffectSpread(Imaging imIn, int distance);
|
||||||
extern Imaging ImagingEffectMandelbrot(int xsize, int ysize,
|
extern Imaging
|
||||||
double extent[4], int quality);
|
ImagingEffectNoise(int xsize, int ysize, float sigma);
|
||||||
|
extern Imaging
|
||||||
|
ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality);
|
||||||
|
|
||||||
/* File I/O */
|
/* File I/O */
|
||||||
/* -------- */
|
/* -------- */
|
||||||
|
|
||||||
/* Built-in drivers */
|
/* Built-in drivers */
|
||||||
extern Imaging ImagingOpenPPM(const char* filename);
|
extern Imaging
|
||||||
extern int ImagingSavePPM(Imaging im, const char* filename);
|
ImagingOpenPPM(const char *filename);
|
||||||
|
extern int
|
||||||
|
ImagingSavePPM(Imaging im, const char *filename);
|
||||||
|
|
||||||
/* Codecs */
|
/* Codecs */
|
||||||
typedef struct ImagingCodecStateInstance *ImagingCodecState;
|
typedef struct ImagingCodecStateInstance *ImagingCodecState;
|
||||||
typedef int (*ImagingCodec)(Imaging im, ImagingCodecState state,
|
typedef int (*ImagingCodec)(
|
||||||
UINT8* buffer, int bytes);
|
Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
|
|
||||||
extern int ImagingBcnDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingBcnDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingBitDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingEpsEncode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, int bytes);
|
ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
extern int ImagingFliDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingGifDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingGifEncode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, int bytes);
|
ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
extern int ImagingHexDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
#ifdef HAVE_LIBJPEG
|
#ifdef HAVE_LIBJPEG
|
||||||
extern int ImagingJpegDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingJpegDecodeCleanup(ImagingCodecState state);
|
extern int
|
||||||
extern int ImagingJpegUseJCSExtensions(void);
|
ImagingJpegDecodeCleanup(ImagingCodecState state);
|
||||||
|
extern int
|
||||||
|
ImagingJpegUseJCSExtensions(void);
|
||||||
|
|
||||||
extern int ImagingJpegEncode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, int bytes);
|
ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_OPENJPEG
|
#ifdef HAVE_OPENJPEG
|
||||||
extern int ImagingJpeg2KDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingJpeg2KDecode(
|
||||||
extern int ImagingJpeg2KDecodeCleanup(ImagingCodecState state);
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingJpeg2KEncode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, int bytes);
|
ImagingJpeg2KDecodeCleanup(ImagingCodecState state);
|
||||||
extern int ImagingJpeg2KEncodeCleanup(ImagingCodecState state);
|
extern int
|
||||||
|
ImagingJpeg2KEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
|
extern int
|
||||||
|
ImagingJpeg2KEncodeCleanup(ImagingCodecState state);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBTIFF
|
#ifdef HAVE_LIBTIFF
|
||||||
extern int ImagingLibTiffDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingLibTiffDecode(
|
||||||
extern int ImagingLibTiffEncode(Imaging im, ImagingCodecState state,
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
UINT8* buffer, int bytes);
|
extern int
|
||||||
|
ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBMPEG
|
#ifdef HAVE_LIBMPEG
|
||||||
extern int ImagingMpegDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingMpegDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
#endif
|
#endif
|
||||||
extern int ImagingMspDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingMspDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingPackbitsDecode(
|
||||||
extern int ImagingPcdDecode(Imaging im, ImagingCodecState state,
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
extern int
|
||||||
extern int ImagingPcxDecode(Imaging im, ImagingCodecState state,
|
ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
extern int
|
||||||
extern int ImagingPcxEncode(Imaging im, ImagingCodecState state,
|
ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
UINT8* buffer, int bytes);
|
extern int
|
||||||
extern int ImagingRawDecode(Imaging im, ImagingCodecState state,
|
ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
extern int
|
||||||
extern int ImagingRawEncode(Imaging im, ImagingCodecState state,
|
ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
UINT8* buffer, int bytes);
|
extern int
|
||||||
extern int ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
extern int
|
||||||
extern int ImagingSunRleDecode(Imaging im, ImagingCodecState state,
|
ImagingSgiRleDecode(
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingSunRleDecode(
|
||||||
extern int ImagingTgaRleEncode(Imaging im, ImagingCodecState state,
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
UINT8* buffer, int bytes);
|
extern int
|
||||||
extern int ImagingXbmDecode(Imaging im, ImagingCodecState state,
|
ImagingTgaRleDecode(
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingXbmEncode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, int bytes);
|
ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
|
extern int
|
||||||
|
ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
|
extern int
|
||||||
|
ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
extern int ImagingZipDecode(Imaging im, ImagingCodecState state,
|
extern int
|
||||||
UINT8* buffer, Py_ssize_t bytes);
|
ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int ImagingZipDecodeCleanup(ImagingCodecState state);
|
extern int
|
||||||
extern int ImagingZipEncode(Imaging im, ImagingCodecState state,
|
ImagingZipDecodeCleanup(ImagingCodecState state);
|
||||||
UINT8* buffer, int bytes);
|
extern int
|
||||||
extern int ImagingZipEncodeCleanup(ImagingCodecState state);
|
ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
|
extern int
|
||||||
|
ImagingZipEncodeCleanup(ImagingCodecState state);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*ImagingShuffler)(UINT8 *out, const UINT8 *in, int pixels);
|
typedef void (*ImagingShuffler)(UINT8 *out, const UINT8 *in, int pixels);
|
||||||
|
|
||||||
/* Public shufflers */
|
/* Public shufflers */
|
||||||
extern void ImagingPackBGR(UINT8* out, const UINT8* in, int pixels);
|
extern void
|
||||||
extern void ImagingUnpackYCC(UINT8* out, const UINT8* in, int pixels);
|
ImagingPackBGR(UINT8 *out, const UINT8 *in, int pixels);
|
||||||
extern void ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels);
|
extern void
|
||||||
|
ImagingUnpackYCC(UINT8 *out, const UINT8 *in, int pixels);
|
||||||
|
extern void
|
||||||
|
ImagingUnpackYCCA(UINT8 *out, const UINT8 *in, int pixels);
|
||||||
|
|
||||||
extern void ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels);
|
extern void
|
||||||
extern void ImagingConvertYCbCr2RGB(UINT8* out, const UINT8* in, int pixels);
|
ImagingConvertRGB2YCbCr(UINT8 *out, const UINT8 *in, int pixels);
|
||||||
|
extern void
|
||||||
|
ImagingConvertYCbCr2RGB(UINT8 *out, const UINT8 *in, int pixels);
|
||||||
|
|
||||||
extern ImagingShuffler ImagingFindUnpacker(const char* mode,
|
extern ImagingShuffler
|
||||||
const char* rawmode, int* bits_out);
|
ImagingFindUnpacker(const char *mode, const char *rawmode, int *bits_out);
|
||||||
extern ImagingShuffler ImagingFindPacker(const char* mode,
|
extern ImagingShuffler
|
||||||
const char* rawmode, int* bits_out);
|
ImagingFindPacker(const char *mode, const char *rawmode, int *bits_out);
|
||||||
|
|
||||||
struct ImagingCodecStateInstance {
|
struct ImagingCodecStateInstance {
|
||||||
int count;
|
int count;
|
||||||
|
@ -509,15 +667,15 @@ struct ImagingCodecStateInstance {
|
||||||
PyObject *fd;
|
PyObject *fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Codec read/write python fd */
|
/* Codec read/write python fd */
|
||||||
extern Py_ssize_t _imaging_read_pyFd(PyObject *fd, char* dest, Py_ssize_t bytes);
|
extern Py_ssize_t
|
||||||
extern Py_ssize_t _imaging_write_pyFd(PyObject *fd, char* src, Py_ssize_t bytes);
|
_imaging_read_pyFd(PyObject *fd, char *dest, Py_ssize_t bytes);
|
||||||
extern int _imaging_seek_pyFd(PyObject *fd, Py_ssize_t offset, int whence);
|
extern Py_ssize_t
|
||||||
extern Py_ssize_t _imaging_tell_pyFd(PyObject *fd);
|
_imaging_write_pyFd(PyObject *fd, char *src, Py_ssize_t bytes);
|
||||||
|
extern int
|
||||||
|
_imaging_seek_pyFd(PyObject *fd, Py_ssize_t offset, int whence);
|
||||||
|
extern Py_ssize_t
|
||||||
|
_imaging_tell_pyFd(PyObject *fd);
|
||||||
|
|
||||||
/* Errcodes */
|
/* Errcodes */
|
||||||
#define IMAGING_CODEC_END 1
|
#define IMAGING_CODEC_END 1
|
||||||
|
@ -527,12 +685,9 @@ extern Py_ssize_t _imaging_tell_pyFd(PyObject *fd);
|
||||||
#define IMAGING_CODEC_CONFIG -8
|
#define IMAGING_CODEC_CONFIG -8
|
||||||
#define IMAGING_CODEC_MEMORY -9
|
#define IMAGING_CODEC_MEMORY -9
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "ImagingUtils.h"
|
#include "ImagingUtils.h"
|
||||||
extern UINT8 *clip8_lookups;
|
extern UINT8 *clip8_lookups;
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,34 +1,29 @@
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
#define MAKE_UINT32(u0, u1, u2, u3) ((UINT32)(u3) | ((UINT32)(u2)<<8) | ((UINT32)(u1)<<16) | ((UINT32)(u0)<<24))
|
#define MAKE_UINT32(u0, u1, u2, u3) \
|
||||||
|
((UINT32)(u3) | ((UINT32)(u2) << 8) | ((UINT32)(u1) << 16) | ((UINT32)(u0) << 24))
|
||||||
#define MASK_UINT32_CHANNEL_0 0xff000000
|
#define MASK_UINT32_CHANNEL_0 0xff000000
|
||||||
#define MASK_UINT32_CHANNEL_1 0x00ff0000
|
#define MASK_UINT32_CHANNEL_1 0x00ff0000
|
||||||
#define MASK_UINT32_CHANNEL_2 0x0000ff00
|
#define MASK_UINT32_CHANNEL_2 0x0000ff00
|
||||||
#define MASK_UINT32_CHANNEL_3 0x000000ff
|
#define MASK_UINT32_CHANNEL_3 0x000000ff
|
||||||
#else
|
#else
|
||||||
#define MAKE_UINT32(u0, u1, u2, u3) ((UINT32)(u0) | ((UINT32)(u1)<<8) | ((UINT32)(u2)<<16) | ((UINT32)(u3)<<24))
|
#define MAKE_UINT32(u0, u1, u2, u3) \
|
||||||
|
((UINT32)(u0) | ((UINT32)(u1) << 8) | ((UINT32)(u2) << 16) | ((UINT32)(u3) << 24))
|
||||||
#define MASK_UINT32_CHANNEL_0 0x000000ff
|
#define MASK_UINT32_CHANNEL_0 0x000000ff
|
||||||
#define MASK_UINT32_CHANNEL_1 0x0000ff00
|
#define MASK_UINT32_CHANNEL_1 0x0000ff00
|
||||||
#define MASK_UINT32_CHANNEL_2 0x00ff0000
|
#define MASK_UINT32_CHANNEL_2 0x00ff0000
|
||||||
#define MASK_UINT32_CHANNEL_3 0xff000000
|
#define MASK_UINT32_CHANNEL_3 0xff000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SHIFTFORDIV255(a) ((((a) >> 8) + a) >> 8)
|
||||||
#define SHIFTFORDIV255(a)\
|
|
||||||
((((a) >> 8) + a) >> 8)
|
|
||||||
|
|
||||||
/* like (a * b + 127) / 255), but much faster on most platforms */
|
/* like (a * b + 127) / 255), but much faster on most platforms */
|
||||||
#define MULDIV255(a, b, tmp)\
|
#define MULDIV255(a, b, tmp) (tmp = (a) * (b) + 128, SHIFTFORDIV255(tmp))
|
||||||
(tmp = (a) * (b) + 128, SHIFTFORDIV255(tmp))
|
|
||||||
|
|
||||||
#define DIV255(a, tmp)\
|
#define DIV255(a, tmp) (tmp = (a) + 128, SHIFTFORDIV255(tmp))
|
||||||
(tmp = (a) + 128, SHIFTFORDIV255(tmp))
|
|
||||||
|
|
||||||
#define BLEND(mask, in1, in2, tmp1)\
|
#define BLEND(mask, in1, in2, tmp1) DIV255(in1 *(255 - mask) + in2 * mask, tmp1)
|
||||||
DIV255(in1 * (255 - mask) + in2 * mask, tmp1)
|
|
||||||
|
|
||||||
#define PREBLEND(mask, in1, in2, tmp1)\
|
|
||||||
(MULDIV255(in1, (255 - mask), tmp1) + in2)
|
|
||||||
|
|
||||||
|
#define PREBLEND(mask, in1, in2, tmp1) (MULDIV255(in1, (255 - mask), tmp1) + in2)
|
||||||
|
|
||||||
#define CLIP8(v) ((v) <= 0 ? 0 : (v) < 256 ? (v) : 255)
|
#define CLIP8(v) ((v) <= 0 ? 0 : (v) < 256 ? (v) : 255)
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,11 @@
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct jpeg_error_mgr pub; /* "public" fields */
|
struct jpeg_error_mgr pub; /* "public" fields */
|
||||||
jmp_buf setjmp_buffer; /* for return to caller */
|
jmp_buf setjmp_buffer; /* for return to caller */
|
||||||
} JPEGERROR;
|
} JPEGERROR;
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Decoder */
|
/* Decoder */
|
||||||
|
|
||||||
|
@ -28,7 +26,6 @@ typedef struct {
|
||||||
} JPEGSOURCE;
|
} JPEGSOURCE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* CONFIGURATION */
|
/* CONFIGURATION */
|
||||||
|
|
||||||
/* Jpeg file mode (empty if not known) */
|
/* Jpeg file mode (empty if not known) */
|
||||||
|
@ -54,7 +51,6 @@ typedef struct {
|
||||||
|
|
||||||
} JPEGSTATE;
|
} JPEGSTATE;
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Encoder */
|
/* Encoder */
|
||||||
|
|
||||||
|
@ -64,7 +60,6 @@ typedef struct {
|
||||||
} JPEGDESTINATION;
|
} JPEGDESTINATION;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* CONFIGURATION */
|
/* CONFIGURATION */
|
||||||
|
|
||||||
/* Quality (0-100, -1 means default) */
|
/* Quality (0-100, -1 means default) */
|
||||||
|
@ -98,7 +93,8 @@ typedef struct {
|
||||||
int qtablesLen;
|
int qtablesLen;
|
||||||
|
|
||||||
/* Extra data (to be injected after header) */
|
/* Extra data (to be injected after header) */
|
||||||
char* extra; int extra_size;
|
char *extra;
|
||||||
|
int extra_size;
|
||||||
|
|
||||||
/* PRIVATE CONTEXT (set by encoder) */
|
/* PRIVATE CONTEXT (set by encoder) */
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,6 @@ typedef struct {
|
||||||
/* PRIVATE CONTEXT (set by decoder) */
|
/* PRIVATE CONTEXT (set by decoder) */
|
||||||
const char *error_msg;
|
const char *error_msg;
|
||||||
|
|
||||||
|
|
||||||
} JPEG2KENCODESTATE;
|
} JPEG2KENCODESTATE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -32,8 +32,7 @@ typedef struct {
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_error(const char *msg, void *client_data)
|
j2k_error(const char *msg, void *client_data) {
|
||||||
{
|
|
||||||
JPEG2KDECODESTATE *state = (JPEG2KDECODESTATE *)client_data;
|
JPEG2KDECODESTATE *state = (JPEG2KDECODESTATE *)client_data;
|
||||||
free((void *)state->error_msg);
|
free((void *)state->error_msg);
|
||||||
state->error_msg = strdup(msg);
|
state->error_msg = strdup(msg);
|
||||||
|
@ -44,8 +43,7 @@ j2k_error(const char *msg, void *client_data)
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
static OPJ_SIZE_T
|
static OPJ_SIZE_T
|
||||||
j2k_read(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
|
j2k_read(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
|
||||||
{
|
|
||||||
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
||||||
|
|
||||||
size_t len = _imaging_read_pyFd(state->fd, p_buffer, p_nb_bytes);
|
size_t len = _imaging_read_pyFd(state->fd, p_buffer, p_nb_bytes);
|
||||||
|
@ -54,8 +52,7 @@ j2k_read(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static OPJ_OFF_T
|
static OPJ_OFF_T
|
||||||
j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data)
|
j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
|
||||||
{
|
|
||||||
off_t pos;
|
off_t pos;
|
||||||
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
||||||
|
|
||||||
|
@ -69,10 +66,8 @@ j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data)
|
||||||
/* Unpackers */
|
/* Unpackers */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef void (*j2k_unpacker_t)(opj_image_t *in,
|
typedef void (*j2k_unpacker_t)(
|
||||||
const JPEG2KTILEINFO *tileInfo,
|
opj_image_t *in, const JPEG2KTILEINFO *tileInfo, const UINT8 *data, Imaging im);
|
||||||
const UINT8 *data,
|
|
||||||
Imaging im);
|
|
||||||
|
|
||||||
struct j2k_decode_unpacker {
|
struct j2k_decode_unpacker {
|
||||||
const char *mode;
|
const char *mode;
|
||||||
|
@ -81,9 +76,8 @@ struct j2k_decode_unpacker {
|
||||||
j2k_unpacker_t unpacker;
|
j2k_unpacker_t unpacker;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline
|
static inline unsigned
|
||||||
unsigned j2ku_shift(unsigned x, int n)
|
j2ku_shift(unsigned x, int n) {
|
||||||
{
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return x >> -n;
|
return x >> -n;
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,9 +86,11 @@ unsigned j2ku_shift(unsigned x, int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_gray_l(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_gray_l(
|
||||||
const UINT8 *tiledata, Imaging im)
|
opj_image_t *in,
|
||||||
{
|
const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata,
|
||||||
|
Imaging im) {
|
||||||
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
unsigned w = tileinfo->x1 - tileinfo->x0;
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
unsigned h = tileinfo->y1 - tileinfo->y0;
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
@ -145,11 +141,12 @@ j2ku_gray_l(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_gray_i(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_gray_i(
|
||||||
const UINT8 *tiledata, Imaging im)
|
opj_image_t *in,
|
||||||
{
|
const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata,
|
||||||
|
Imaging im) {
|
||||||
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
unsigned w = tileinfo->x1 - tileinfo->x0;
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
unsigned h = tileinfo->y1 - tileinfo->y0;
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
@ -199,11 +196,12 @@ j2ku_gray_i(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_gray_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_gray_rgb(
|
||||||
const UINT8 *tiledata, Imaging im)
|
opj_image_t *in,
|
||||||
{
|
const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata,
|
||||||
|
Imaging im) {
|
||||||
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
unsigned w = tileinfo->x1 - tileinfo->x0;
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
unsigned h = tileinfo->y1 - tileinfo->y0;
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
@ -263,9 +261,11 @@ j2ku_gray_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_graya_la(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_graya_la(
|
||||||
const UINT8 *tiledata, Imaging im)
|
opj_image_t *in,
|
||||||
{
|
const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata,
|
||||||
|
Imaging im) {
|
||||||
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
unsigned w = tileinfo->x1 - tileinfo->x0;
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
unsigned h = tileinfo->y1 - tileinfo->y0;
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
@ -304,15 +304,31 @@ j2ku_graya_la(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
UINT32 word = 0, aword = 0, byte;
|
UINT32 word = 0, aword = 0, byte;
|
||||||
|
|
||||||
switch (csiz) {
|
switch (csiz) {
|
||||||
case 1: word = *data++; break;
|
case 1:
|
||||||
case 2: word = *(const UINT16 *)data; data += 2; break;
|
word = *data++;
|
||||||
case 4: word = *(const UINT32 *)data; data += 4; break;
|
break;
|
||||||
|
case 2:
|
||||||
|
word = *(const UINT16 *)data;
|
||||||
|
data += 2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
word = *(const UINT32 *)data;
|
||||||
|
data += 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (acsiz) {
|
switch (acsiz) {
|
||||||
case 1: aword = *adata++; break;
|
case 1:
|
||||||
case 2: aword = *(const UINT16 *)adata; adata += 2; break;
|
aword = *adata++;
|
||||||
case 4: aword = *(const UINT32 *)adata; adata += 4; break;
|
break;
|
||||||
|
case 2:
|
||||||
|
aword = *(const UINT16 *)adata;
|
||||||
|
adata += 2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
aword = *(const UINT32 *)adata;
|
||||||
|
adata += 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte = j2ku_shift(offset + word, shift);
|
byte = j2ku_shift(offset + word, shift);
|
||||||
|
@ -324,9 +340,11 @@ j2ku_graya_la(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_srgb_rgb(
|
||||||
const UINT8 *tiledata, Imaging im)
|
opj_image_t *in,
|
||||||
{
|
const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata,
|
||||||
|
Imaging im) {
|
||||||
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
unsigned w = tileinfo->x1 - tileinfo->x0;
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
unsigned h = tileinfo->y1 - tileinfo->y0;
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
@ -365,9 +383,17 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
UINT32 word = 0;
|
UINT32 word = 0;
|
||||||
|
|
||||||
switch (csiz[n]) {
|
switch (csiz[n]) {
|
||||||
case 1: word = *data[n]++; break;
|
case 1:
|
||||||
case 2: word = *(const UINT16 *)data[n]; data[n] += 2; break;
|
word = *data[n]++;
|
||||||
case 4: word = *(const UINT32 *)data[n]; data[n] += 4; break;
|
break;
|
||||||
|
case 2:
|
||||||
|
word = *(const UINT16 *)data[n];
|
||||||
|
data[n] += 2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
word = *(const UINT32 *)data[n];
|
||||||
|
data[n] += 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
row[n] = j2ku_shift(offsets[n] + word, shifts[n]);
|
row[n] = j2ku_shift(offsets[n] + word, shifts[n]);
|
||||||
|
@ -379,9 +405,11 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_sycc_rgb(
|
||||||
const UINT8 *tiledata, Imaging im)
|
opj_image_t *in,
|
||||||
{
|
const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata,
|
||||||
|
Imaging im) {
|
||||||
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
unsigned w = tileinfo->x1 - tileinfo->x0;
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
unsigned h = tileinfo->y1 - tileinfo->y0;
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
@ -421,9 +449,17 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
UINT32 word = 0;
|
UINT32 word = 0;
|
||||||
|
|
||||||
switch (csiz[n]) {
|
switch (csiz[n]) {
|
||||||
case 1: word = *data[n]++; break;
|
case 1:
|
||||||
case 2: word = *(const UINT16 *)data[n]; data[n] += 2; break;
|
word = *data[n]++;
|
||||||
case 4: word = *(const UINT32 *)data[n]; data[n] += 4; break;
|
break;
|
||||||
|
case 2:
|
||||||
|
word = *(const UINT16 *)data[n];
|
||||||
|
data[n] += 2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
word = *(const UINT32 *)data[n];
|
||||||
|
data[n] += 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
row[n] = j2ku_shift(offsets[n] + word, shifts[n]);
|
row[n] = j2ku_shift(offsets[n] + word, shifts[n]);
|
||||||
|
@ -437,9 +473,11 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_srgba_rgba(
|
||||||
const UINT8 *tiledata, Imaging im)
|
opj_image_t *in,
|
||||||
{
|
const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata,
|
||||||
|
Imaging im) {
|
||||||
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
unsigned w = tileinfo->x1 - tileinfo->x0;
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
unsigned h = tileinfo->y1 - tileinfo->y0;
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
@ -478,9 +516,17 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
UINT32 word = 0;
|
UINT32 word = 0;
|
||||||
|
|
||||||
switch (csiz[n]) {
|
switch (csiz[n]) {
|
||||||
case 1: word = *data[n]++; break;
|
case 1:
|
||||||
case 2: word = *(const UINT16 *)data[n]; data[n] += 2; break;
|
word = *data[n]++;
|
||||||
case 4: word = *(const UINT32 *)data[n]; data[n] += 4; break;
|
break;
|
||||||
|
case 2:
|
||||||
|
word = *(const UINT16 *)data[n];
|
||||||
|
data[n] += 2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
word = *(const UINT32 *)data[n];
|
||||||
|
data[n] += 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
row[n] = j2ku_shift(offsets[n] + word, shifts[n]);
|
row[n] = j2ku_shift(offsets[n] + word, shifts[n]);
|
||||||
|
@ -491,9 +537,11 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
j2ku_sycca_rgba(
|
||||||
const UINT8 *tiledata, Imaging im)
|
opj_image_t *in,
|
||||||
{
|
const JPEG2KTILEINFO *tileinfo,
|
||||||
|
const UINT8 *tiledata,
|
||||||
|
Imaging im) {
|
||||||
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
|
||||||
unsigned w = tileinfo->x1 - tileinfo->x0;
|
unsigned w = tileinfo->x1 - tileinfo->x0;
|
||||||
unsigned h = tileinfo->y1 - tileinfo->y0;
|
unsigned h = tileinfo->y1 - tileinfo->y0;
|
||||||
|
@ -533,9 +581,17 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
|
||||||
UINT32 word = 0;
|
UINT32 word = 0;
|
||||||
|
|
||||||
switch (csiz[n]) {
|
switch (csiz[n]) {
|
||||||
case 1: word = *data[n]++; break;
|
case 1:
|
||||||
case 2: word = *(const UINT16 *)data[n]; data[n] += 2; break;
|
word = *data[n]++;
|
||||||
case 4: word = *(const UINT32 *)data[n]; data[n] += 4; break;
|
break;
|
||||||
|
case 2:
|
||||||
|
word = *(const UINT16 *)data[n];
|
||||||
|
data[n] += 2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
word = *(const UINT32 *)data[n];
|
||||||
|
data[n] += 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
row[n] = j2ku_shift(offsets[n] + word, shifts[n]);
|
row[n] = j2ku_shift(offsets[n] + word, shifts[n]);
|
||||||
|
@ -578,8 +634,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
j2k_decode_entry(Imaging im, ImagingCodecState state)
|
j2k_decode_entry(Imaging im, ImagingCodecState state) {
|
||||||
{
|
|
||||||
JPEG2KDECODESTATE *context = (JPEG2KDECODESTATE *)state->context;
|
JPEG2KDECODESTATE *context = (JPEG2KDECODESTATE *)state->context;
|
||||||
opj_stream_t *stream = NULL;
|
opj_stream_t *stream = NULL;
|
||||||
opj_image_t *image = NULL;
|
opj_image_t *image = NULL;
|
||||||
|
@ -591,7 +646,6 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
unsigned n, tile_height, tile_width;
|
unsigned n, tile_height, tile_width;
|
||||||
int components;
|
int components;
|
||||||
|
|
||||||
|
|
||||||
stream = opj_stream_create(BUFFER_SIZE, OPJ_TRUE);
|
stream = opj_stream_create(BUFFER_SIZE, OPJ_TRUE);
|
||||||
|
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
|
@ -645,8 +699,8 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that this image is something we can handle */
|
/* Check that this image is something we can handle */
|
||||||
if (image->numcomps < 1 || image->numcomps > 4
|
if (image->numcomps < 1 || image->numcomps > 4 ||
|
||||||
|| image->color_space == OPJ_CLRSPC_UNKNOWN) {
|
image->color_space == OPJ_CLRSPC_UNKNOWN) {
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
state->state = J2K_STATE_FAILED;
|
state->state = J2K_STATE_FAILED;
|
||||||
goto quick_exit;
|
goto quick_exit;
|
||||||
|
@ -686,15 +740,21 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
|
|
||||||
if (color_space == OPJ_CLRSPC_UNSPECIFIED) {
|
if (color_space == OPJ_CLRSPC_UNSPECIFIED) {
|
||||||
switch (image->numcomps) {
|
switch (image->numcomps) {
|
||||||
case 1: case 2: color_space = OPJ_CLRSPC_GRAY; break;
|
case 1:
|
||||||
case 3: case 4: color_space = OPJ_CLRSPC_SRGB; break;
|
case 2:
|
||||||
|
color_space = OPJ_CLRSPC_GRAY;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
color_space = OPJ_CLRSPC_SRGB;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = 0; n < sizeof(j2k_unpackers) / sizeof(j2k_unpackers[0]); ++n) {
|
for (n = 0; n < sizeof(j2k_unpackers) / sizeof(j2k_unpackers[0]); ++n) {
|
||||||
if (color_space == j2k_unpackers[n].color_space
|
if (color_space == j2k_unpackers[n].color_space &&
|
||||||
&& image->numcomps == j2k_unpackers[n].components
|
image->numcomps == j2k_unpackers[n].components &&
|
||||||
&& strcmp (im->mode, j2k_unpackers[n].mode) == 0) {
|
strcmp(im->mode, j2k_unpackers[n].mode) == 0) {
|
||||||
unpack = j2k_unpackers[n].unpacker;
|
unpack = j2k_unpackers[n].unpacker;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -713,12 +773,15 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
OPJ_BOOL should_continue;
|
OPJ_BOOL should_continue;
|
||||||
unsigned correction = (1 << params.cp_reduce) - 1;
|
unsigned correction = (1 << params.cp_reduce) - 1;
|
||||||
|
|
||||||
if (!opj_read_tile_header(codec,
|
if (!opj_read_tile_header(
|
||||||
|
codec,
|
||||||
stream,
|
stream,
|
||||||
&tile_info.tile_index,
|
&tile_info.tile_index,
|
||||||
&tile_info.data_size,
|
&tile_info.data_size,
|
||||||
&tile_info.x0, &tile_info.y0,
|
&tile_info.x0,
|
||||||
&tile_info.x1, &tile_info.y1,
|
&tile_info.y0,
|
||||||
|
&tile_info.x1,
|
||||||
|
&tile_info.y1,
|
||||||
&tile_info.nb_comps,
|
&tile_info.nb_comps,
|
||||||
&should_continue)) {
|
&should_continue)) {
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
|
@ -740,14 +803,12 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
/* Check the tile bounds; if the tile is outside the image area,
|
/* Check the tile bounds; if the tile is outside the image area,
|
||||||
or if it has a negative width or height (i.e. the coordinates are
|
or if it has a negative width or height (i.e. the coordinates are
|
||||||
swapped), bail. */
|
swapped), bail. */
|
||||||
if (tile_info.x0 >= tile_info.x1
|
if (tile_info.x0 >= tile_info.x1 || tile_info.y0 >= tile_info.y1 ||
|
||||||
|| tile_info.y0 >= tile_info.y1
|
tile_info.x0 < 0 || tile_info.y0 < 0 ||
|
||||||
|| tile_info.x0 < 0
|
(OPJ_UINT32)tile_info.x0 < image->x0 ||
|
||||||
|| tile_info.y0 < 0
|
(OPJ_UINT32)tile_info.y0 < image->y0 ||
|
||||||
|| (OPJ_UINT32)tile_info.x0 < image->x0
|
(OPJ_INT32)(tile_info.x1 - image->x0) > im->xsize ||
|
||||||
|| (OPJ_UINT32)tile_info.y0 < image->y0
|
(OPJ_INT32)(tile_info.y1 - image->y0) > im->ysize) {
|
||||||
|| (OPJ_INT32)(tile_info.x1 - image->x0) > im->xsize
|
|
||||||
|| (OPJ_INT32)(tile_info.y1 - image->y0) > im->ysize) {
|
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
state->state = J2K_STATE_FAILED;
|
state->state = J2K_STATE_FAILED;
|
||||||
goto quick_exit;
|
goto quick_exit;
|
||||||
|
@ -787,8 +848,8 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
buffer_size = tile_info.data_size;
|
buffer_size = tile_info.data_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!opj_decode_tile_data(
|
||||||
if (!opj_decode_tile_data(codec,
|
codec,
|
||||||
tile_info.tile_index,
|
tile_info.tile_index,
|
||||||
(OPJ_BYTE *)state->buffer,
|
(OPJ_BYTE *)state->buffer,
|
||||||
tile_info.data_size,
|
tile_info.data_size,
|
||||||
|
@ -831,9 +892,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingJpeg2KDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingJpeg2KDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
|
|
||||||
if (bytes) {
|
if (bytes) {
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
state->state = J2K_STATE_FAILED;
|
state->state = J2K_STATE_FAILED;
|
||||||
|
@ -876,8 +935,7 @@ ImagingJpeg2KDecodeCleanup(ImagingCodecState state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
ImagingJpeg2KVersion(void)
|
ImagingJpeg2KVersion(void) {
|
||||||
{
|
|
||||||
return opj_version();
|
return opj_version();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,16 +29,14 @@
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_error(const char *msg, void *client_data)
|
j2k_error(const char *msg, void *client_data) {
|
||||||
{
|
|
||||||
JPEG2KENCODESTATE *state = (JPEG2KENCODESTATE *)client_data;
|
JPEG2KENCODESTATE *state = (JPEG2KENCODESTATE *)client_data;
|
||||||
free((void *)state->error_msg);
|
free((void *)state->error_msg);
|
||||||
state->error_msg = strdup(msg);
|
state->error_msg = strdup(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_warn(const char *msg, void *client_data)
|
j2k_warn(const char *msg, void *client_data) {
|
||||||
{
|
|
||||||
// Null handler
|
// Null handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,8 +45,7 @@ j2k_warn(const char *msg, void *client_data)
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
static OPJ_SIZE_T
|
static OPJ_SIZE_T
|
||||||
j2k_write(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
|
j2k_write(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
|
||||||
{
|
|
||||||
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
|
|
||||||
|
@ -57,10 +54,8 @@ j2k_write(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
|
||||||
return result ? result : (OPJ_SIZE_T)-1;
|
return result ? result : (OPJ_SIZE_T)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static OPJ_OFF_T
|
static OPJ_OFF_T
|
||||||
j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data)
|
j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
|
||||||
{
|
|
||||||
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int result;
|
int result;
|
||||||
|
@ -79,8 +74,7 @@ j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static OPJ_BOOL
|
static OPJ_BOOL
|
||||||
j2k_seek(OPJ_OFF_T p_nb_bytes, void *p_user_data)
|
j2k_seek(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
|
||||||
{
|
|
||||||
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
ImagingCodecState state = (ImagingCodecState)p_user_data;
|
||||||
off_t pos = 0;
|
off_t pos = 0;
|
||||||
|
|
||||||
|
@ -94,14 +88,11 @@ j2k_seek(OPJ_OFF_T p_nb_bytes, void *p_user_data)
|
||||||
/* Encoder */
|
/* Encoder */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef void (*j2k_pack_tile_t)(Imaging im, UINT8 *buf,
|
typedef void (*j2k_pack_tile_t)(
|
||||||
unsigned x0, unsigned y0,
|
Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h);
|
||||||
unsigned w, unsigned h);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_pack_l(Imaging im, UINT8 *buf,
|
j2k_pack_l(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
|
||||||
unsigned x0, unsigned y0, unsigned w, unsigned h)
|
|
||||||
{
|
|
||||||
UINT8 *ptr = buf;
|
UINT8 *ptr = buf;
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
for (y = 0; y < h; ++y) {
|
for (y = 0; y < h; ++y) {
|
||||||
|
@ -113,9 +104,7 @@ j2k_pack_l(Imaging im, UINT8 *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_pack_i16(Imaging im, UINT8 *buf,
|
j2k_pack_i16(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
|
||||||
unsigned x0, unsigned y0, unsigned w, unsigned h)
|
|
||||||
{
|
|
||||||
UINT8 *ptr = buf;
|
UINT8 *ptr = buf;
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
for (y = 0; y < h; ++y) {
|
for (y = 0; y < h; ++y) {
|
||||||
|
@ -127,11 +116,8 @@ j2k_pack_i16(Imaging im, UINT8 *buf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_pack_la(Imaging im, UINT8 *buf,
|
j2k_pack_la(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
|
||||||
unsigned x0, unsigned y0, unsigned w, unsigned h)
|
|
||||||
{
|
|
||||||
UINT8 *ptr = buf;
|
UINT8 *ptr = buf;
|
||||||
UINT8 *ptra = buf + w * h;
|
UINT8 *ptra = buf + w * h;
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
|
@ -146,9 +132,7 @@ j2k_pack_la(Imaging im, UINT8 *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_pack_rgb(Imaging im, UINT8 *buf,
|
j2k_pack_rgb(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
|
||||||
unsigned x0, unsigned y0, unsigned w, unsigned h)
|
|
||||||
{
|
|
||||||
UINT8 *pr = buf;
|
UINT8 *pr = buf;
|
||||||
UINT8 *pg = pr + w * h;
|
UINT8 *pg = pr + w * h;
|
||||||
UINT8 *pb = pg + w * h;
|
UINT8 *pb = pg + w * h;
|
||||||
|
@ -165,9 +149,8 @@ j2k_pack_rgb(Imaging im, UINT8 *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_pack_rgba(Imaging im, UINT8 *buf,
|
j2k_pack_rgba(
|
||||||
unsigned x0, unsigned y0, unsigned w, unsigned h)
|
Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
|
||||||
{
|
|
||||||
UINT8 *pr = buf;
|
UINT8 *pr = buf;
|
||||||
UINT8 *pg = pr + w * h;
|
UINT8 *pg = pr + w * h;
|
||||||
UINT8 *pb = pg + w * h;
|
UINT8 *pb = pg + w * h;
|
||||||
|
@ -192,8 +175,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params)
|
j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params) {
|
||||||
{
|
|
||||||
float rate;
|
float rate;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
@ -215,8 +197,9 @@ j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params)
|
||||||
params->irreversible = 1;
|
params->irreversible = 1;
|
||||||
|
|
||||||
if (params->cp_cinema == OPJ_CINEMA4K_24) {
|
if (params->cp_cinema == OPJ_CINEMA4K_24) {
|
||||||
float max_rate = ((float)(components * im->xsize * im->ysize * 8)
|
float max_rate =
|
||||||
/ (CINEMA_24_CS_LENGTH * 8));
|
((float)(components * im->xsize * im->ysize * 8) /
|
||||||
|
(CINEMA_24_CS_LENGTH * 8));
|
||||||
|
|
||||||
params->POC[0].tile = 1;
|
params->POC[0].tile = 1;
|
||||||
params->POC[0].resno0 = 0;
|
params->POC[0].resno0 = 0;
|
||||||
|
@ -239,8 +222,9 @@ j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params)
|
||||||
if (params->tcp_rates[0] == 0) {
|
if (params->tcp_rates[0] == 0) {
|
||||||
params->tcp_rates[n] = max_rate;
|
params->tcp_rates[n] = max_rate;
|
||||||
} else {
|
} else {
|
||||||
rate = ((float)(components * im->xsize * im->ysize * 8)
|
rate =
|
||||||
/ (params->tcp_rates[n] * 8));
|
((float)(components * im->xsize * im->ysize * 8) /
|
||||||
|
(params->tcp_rates[n] * 8));
|
||||||
if (rate > CINEMA_24_CS_LENGTH) {
|
if (rate > CINEMA_24_CS_LENGTH) {
|
||||||
params->tcp_rates[n] = max_rate;
|
params->tcp_rates[n] = max_rate;
|
||||||
}
|
}
|
||||||
|
@ -249,16 +233,18 @@ j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params)
|
||||||
|
|
||||||
params->max_comp_size = COMP_24_CS_MAX_LENGTH;
|
params->max_comp_size = COMP_24_CS_MAX_LENGTH;
|
||||||
} else {
|
} else {
|
||||||
float max_rate = ((float)(components * im->xsize * im->ysize * 8)
|
float max_rate =
|
||||||
/ (CINEMA_48_CS_LENGTH * 8));
|
((float)(components * im->xsize * im->ysize * 8) /
|
||||||
|
(CINEMA_48_CS_LENGTH * 8));
|
||||||
|
|
||||||
for (n = 0; n < params->tcp_numlayers; ++n) {
|
for (n = 0; n < params->tcp_numlayers; ++n) {
|
||||||
rate = 0;
|
rate = 0;
|
||||||
if (params->tcp_rates[0] == 0) {
|
if (params->tcp_rates[0] == 0) {
|
||||||
params->tcp_rates[n] = max_rate;
|
params->tcp_rates[n] = max_rate;
|
||||||
} else {
|
} else {
|
||||||
rate = ((float)(components * im->xsize * im->ysize * 8)
|
rate =
|
||||||
/ (params->tcp_rates[n] * 8));
|
((float)(components * im->xsize * im->ysize * 8) /
|
||||||
|
(params->tcp_rates[n] * 8));
|
||||||
if (rate > CINEMA_48_CS_LENGTH) {
|
if (rate > CINEMA_48_CS_LENGTH) {
|
||||||
params->tcp_rates[n] = max_rate;
|
params->tcp_rates[n] = max_rate;
|
||||||
}
|
}
|
||||||
|
@ -270,8 +256,7 @@ j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
j2k_encode_entry(Imaging im, ImagingCodecState state)
|
j2k_encode_entry(Imaging im, ImagingCodecState state) {
|
||||||
{
|
|
||||||
JPEG2KENCODESTATE *context = (JPEG2KENCODESTATE *)state->context;
|
JPEG2KENCODESTATE *context = (JPEG2KENCODESTATE *)state->context;
|
||||||
opj_stream_t *stream = NULL;
|
opj_stream_t *stream = NULL;
|
||||||
opj_image_t *image = NULL;
|
opj_image_t *image = NULL;
|
||||||
|
@ -400,7 +385,8 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
|
||||||
float *pq;
|
float *pq;
|
||||||
|
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if ((unsigned)len > sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0])) {
|
if ((unsigned)len >
|
||||||
|
sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0])) {
|
||||||
len = sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0]);
|
len = sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,16 +417,16 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
|
||||||
params.numresolution = context->num_resolutions;
|
params.numresolution = context->num_resolutions;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->cblk_width >= 4 && context->cblk_width <= 1024
|
if (context->cblk_width >= 4 && context->cblk_width <= 1024 &&
|
||||||
&& context->cblk_height >= 4 && context->cblk_height <= 1024
|
context->cblk_height >= 4 && context->cblk_height <= 1024 &&
|
||||||
&& context->cblk_width * context->cblk_height <= 4096) {
|
context->cblk_width * context->cblk_height <= 4096) {
|
||||||
params.cblockw_init = context->cblk_width;
|
params.cblockw_init = context->cblk_width;
|
||||||
params.cblockh_init = context->cblk_height;
|
params.cblockh_init = context->cblk_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->precinct_width >= 4 && context->precinct_height >= 4
|
if (context->precinct_width >= 4 && context->precinct_height >= 4 &&
|
||||||
&& context->precinct_width >= context->cblk_width
|
context->precinct_width >= context->cblk_width &&
|
||||||
&& context->precinct_height > context->cblk_height) {
|
context->precinct_height > context->cblk_height) {
|
||||||
params.prcw_init[0] = context->precinct_width;
|
params.prcw_init[0] = context->precinct_width;
|
||||||
params.prch_init[0] = context->precinct_height;
|
params.prch_init[0] = context->precinct_height;
|
||||||
params.res_spec = 1;
|
params.res_spec = 1;
|
||||||
|
@ -504,10 +490,10 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write each tile */
|
/* Write each tile */
|
||||||
tiles_x = (im->xsize + (params.image_offset_x0 - params.cp_tx0)
|
tiles_x = (im->xsize + (params.image_offset_x0 - params.cp_tx0) + tile_width - 1) /
|
||||||
+ tile_width - 1) / tile_width;
|
tile_width;
|
||||||
tiles_y = (im->ysize + (params.image_offset_y0 - params.cp_ty0)
|
tiles_y = (im->ysize + (params.image_offset_y0 - params.cp_ty0) + tile_height - 1) /
|
||||||
+ tile_height - 1) / tile_height;
|
tile_height;
|
||||||
|
|
||||||
/* check for integer overflow for the malloc line, checking any expression
|
/* check for integer overflow for the malloc line, checking any expression
|
||||||
that may multiply either tile_width or tile_height */
|
that may multiply either tile_width or tile_height */
|
||||||
|
@ -564,8 +550,7 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
|
||||||
|
|
||||||
data_size = pixw * pixh * components * prec / 8;
|
data_size = pixw * pixh * components * prec / 8;
|
||||||
|
|
||||||
if (!opj_write_tile(codec, tile_ndx++, state->buffer,
|
if (!opj_write_tile(codec, tile_ndx++, state->buffer, data_size, stream)) {
|
||||||
data_size, stream)) {
|
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
state->state = J2K_STATE_FAILED;
|
state->state = J2K_STATE_FAILED;
|
||||||
goto quick_exit;
|
goto quick_exit;
|
||||||
|
@ -598,14 +583,12 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingJpeg2KEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes)
|
ImagingJpeg2KEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
if (state->state == J2K_STATE_FAILED) {
|
if (state->state == J2K_STATE_FAILED) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->state == J2K_STATE_START) {
|
if (state->state == J2K_STATE_START) {
|
||||||
|
|
||||||
state->state = J2K_STATE_ENCODING;
|
state->state = J2K_STATE_ENCODING;
|
||||||
|
|
||||||
return j2k_encode_entry(im, state);
|
return j2k_encode_entry(im, state);
|
||||||
|
@ -633,7 +616,6 @@ ImagingJpeg2KEncodeCleanup(ImagingCodecState state) {
|
||||||
|
|
||||||
context->error_msg = NULL;
|
context->error_msg = NULL;
|
||||||
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
* See the README file for details on usage and redistribution.
|
* See the README file for details on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBJPEG
|
#ifdef HAVE_LIBJPEG
|
||||||
|
@ -37,7 +36,6 @@
|
||||||
|
|
||||||
#include "Jpeg.h"
|
#include "Jpeg.h"
|
||||||
|
|
||||||
|
|
||||||
#define STRINGIFY(x) #x
|
#define STRINGIFY(x) #x
|
||||||
#define TOSTRING(x) STRINGIFY(x)
|
#define TOSTRING(x) STRINGIFY(x)
|
||||||
|
|
||||||
|
@ -50,8 +48,7 @@ char *libjpeg_turbo_version = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingJpegUseJCSExtensions()
|
ImagingJpegUseJCSExtensions() {
|
||||||
{
|
|
||||||
int use_jcs_extensions = 0;
|
int use_jcs_extensions = 0;
|
||||||
#ifdef JCS_EXTENSIONS
|
#ifdef JCS_EXTENSIONS
|
||||||
#if defined(LIBJPEG_TURBO_VERSION_NUMBER)
|
#if defined(LIBJPEG_TURBO_VERSION_NUMBER)
|
||||||
|
@ -72,21 +69,16 @@ ImagingJpegUseJCSExtensions()
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
METHODDEF(void)
|
METHODDEF(void)
|
||||||
stub(j_decompress_ptr cinfo)
|
stub(j_decompress_ptr cinfo) { /* empty */ }
|
||||||
{
|
|
||||||
/* empty */
|
|
||||||
}
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
METHODDEF(boolean)
|
||||||
fill_input_buffer(j_decompress_ptr cinfo)
|
fill_input_buffer(j_decompress_ptr cinfo) {
|
||||||
{
|
|
||||||
/* Suspension */
|
/* Suspension */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHODDEF(void)
|
METHODDEF(void)
|
||||||
skip_input_data(j_decompress_ptr cinfo, long num_bytes)
|
skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
|
||||||
{
|
|
||||||
JPEGSOURCE *source = (JPEGSOURCE *)cinfo->src;
|
JPEGSOURCE *source = (JPEGSOURCE *)cinfo->src;
|
||||||
|
|
||||||
if (num_bytes > (long)source->pub.bytes_in_buffer) {
|
if (num_bytes > (long)source->pub.bytes_in_buffer) {
|
||||||
|
@ -103,10 +95,8 @@ skip_input_data(j_decompress_ptr cinfo, long num_bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GLOBAL(void)
|
GLOBAL(void)
|
||||||
jpeg_buffer_src(j_decompress_ptr cinfo, JPEGSOURCE* source)
|
jpeg_buffer_src(j_decompress_ptr cinfo, JPEGSOURCE *source) {
|
||||||
{
|
|
||||||
cinfo->src = (void *)source;
|
cinfo->src = (void *)source;
|
||||||
|
|
||||||
/* Prepare for suspending reader */
|
/* Prepare for suspending reader */
|
||||||
|
@ -120,32 +110,26 @@ jpeg_buffer_src(j_decompress_ptr cinfo, JPEGSOURCE* source)
|
||||||
source->skip = 0;
|
source->skip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Error handler */
|
/* Error handler */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
METHODDEF(void)
|
METHODDEF(void)
|
||||||
error(j_common_ptr cinfo)
|
error(j_common_ptr cinfo) {
|
||||||
{
|
|
||||||
JPEGERROR *error;
|
JPEGERROR *error;
|
||||||
error = (JPEGERROR *)cinfo->err;
|
error = (JPEGERROR *)cinfo->err;
|
||||||
longjmp(error->setjmp_buffer, 1);
|
longjmp(error->setjmp_buffer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHODDEF(void)
|
METHODDEF(void)
|
||||||
output(j_common_ptr cinfo)
|
output(j_common_ptr cinfo) { /* nothing */ }
|
||||||
{
|
|
||||||
/* nothing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Decoder */
|
/* Decoder */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
JPEGSTATE *context = (JPEGSTATE *)state->context;
|
JPEGSTATE *context = (JPEGSTATE *)state->context;
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
|
@ -157,7 +141,6 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state->state) {
|
if (!state->state) {
|
||||||
|
|
||||||
/* Setup decompression context */
|
/* Setup decompression context */
|
||||||
context->cinfo.err = jpeg_std_error(&context->error.pub);
|
context->cinfo.err = jpeg_std_error(&context->error.pub);
|
||||||
context->error.pub.error_exit = error;
|
context->error.pub.error_exit = error;
|
||||||
|
@ -167,7 +150,6 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
|
||||||
|
|
||||||
/* Ready to decode */
|
/* Ready to decode */
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the source buffer */
|
/* Load the source buffer */
|
||||||
|
@ -182,12 +164,10 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state->state) {
|
switch (state->state) {
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
|
||||||
/* Read JPEG header, until we find an image body. */
|
/* Read JPEG header, until we find an image body. */
|
||||||
do {
|
do {
|
||||||
|
|
||||||
/* Note that we cannot return unless we have decoded
|
/* Note that we cannot return unless we have decoded
|
||||||
as much data as possible. */
|
as much data as possible. */
|
||||||
ok = jpeg_read_header(&context->cinfo, FALSE);
|
ok = jpeg_read_header(&context->cinfo, FALSE);
|
||||||
|
@ -226,7 +206,8 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
|
||||||
context->cinfo.out_color_space = JCS_EXT_RGBX;
|
context->cinfo.out_color_space = JCS_EXT_RGBX;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (strcmp(context->rawmode, "CMYK") == 0 ||
|
else if (
|
||||||
|
strcmp(context->rawmode, "CMYK") == 0 ||
|
||||||
strcmp(context->rawmode, "CMYK;I") == 0) {
|
strcmp(context->rawmode, "CMYK;I") == 0) {
|
||||||
context->cinfo.out_color_space = JCS_CMYK;
|
context->cinfo.out_color_space = JCS_CMYK;
|
||||||
} else if (strcmp(context->rawmode, "YCbCr") == 0) {
|
} else if (strcmp(context->rawmode, "YCbCr") == 0) {
|
||||||
|
@ -271,8 +252,10 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
|
||||||
if (ok != 1) {
|
if (ok != 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
state->shuffle(
|
||||||
state->xoff * im->pixelsize, state->buffer,
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
|
state->xoff * im->pixelsize,
|
||||||
|
state->buffer,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
state->y++;
|
state->y++;
|
||||||
}
|
}
|
||||||
|
@ -296,19 +279,18 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
|
||||||
jpeg_destroy_decompress(&context->cinfo);
|
jpeg_destroy_decompress(&context->cinfo);
|
||||||
/* if (jerr.pub.num_warnings) return BROKEN; */
|
/* if (jerr.pub.num_warnings) return BROKEN; */
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return number of bytes consumed */
|
/* Return number of bytes consumed */
|
||||||
return context->source.pub.next_input_byte - buf;
|
return context->source.pub.next_input_byte - buf;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
int ImagingJpegDecodeCleanup(ImagingCodecState state){
|
int
|
||||||
|
ImagingJpegDecodeCleanup(ImagingCodecState state) {
|
||||||
/* called to free the decompression engine when the decode terminates
|
/* called to free the decompression engine when the decode terminates
|
||||||
due to a corrupt or truncated image
|
due to a corrupt or truncated image
|
||||||
*/
|
*/
|
||||||
|
@ -320,4 +302,3 @@ int ImagingJpegDecodeCleanup(ImagingCodecState state){
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
* See the README file for details on usage and redistribution.
|
* See the README file for details on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBJPEG
|
#ifdef HAVE_LIBJPEG
|
||||||
|
@ -40,21 +39,16 @@
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
METHODDEF(void)
|
METHODDEF(void)
|
||||||
stub(j_compress_ptr cinfo)
|
stub(j_compress_ptr cinfo) { /* empty */ }
|
||||||
{
|
|
||||||
/* empty */
|
|
||||||
}
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
METHODDEF(boolean)
|
||||||
empty_output_buffer (j_compress_ptr cinfo)
|
empty_output_buffer(j_compress_ptr cinfo) {
|
||||||
{
|
|
||||||
/* Suspension */
|
/* Suspension */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBAL(void)
|
GLOBAL(void)
|
||||||
jpeg_buffer_dest(j_compress_ptr cinfo, JPEGDESTINATION* destination)
|
jpeg_buffer_dest(j_compress_ptr cinfo, JPEGDESTINATION *destination) {
|
||||||
{
|
|
||||||
cinfo->dest = (void *)destination;
|
cinfo->dest = (void *)destination;
|
||||||
|
|
||||||
destination->pub.init_destination = stub;
|
destination->pub.init_destination = stub;
|
||||||
|
@ -62,28 +56,24 @@ jpeg_buffer_dest(j_compress_ptr cinfo, JPEGDESTINATION* destination)
|
||||||
destination->pub.term_destination = stub;
|
destination->pub.term_destination = stub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Error handler */
|
/* Error handler */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
METHODDEF(void)
|
METHODDEF(void)
|
||||||
error(j_common_ptr cinfo)
|
error(j_common_ptr cinfo) {
|
||||||
{
|
|
||||||
JPEGERROR *error;
|
JPEGERROR *error;
|
||||||
error = (JPEGERROR *)cinfo->err;
|
error = (JPEGERROR *)cinfo->err;
|
||||||
(*cinfo->err->output_message)(cinfo);
|
(*cinfo->err->output_message)(cinfo);
|
||||||
longjmp(error->setjmp_buffer, 1);
|
longjmp(error->setjmp_buffer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Encoder */
|
/* Encoder */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
JPEGENCODERSTATE *context = (JPEGENCODERSTATE *)state->context;
|
JPEGENCODERSTATE *context = (JPEGENCODERSTATE *)state->context;
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
|
@ -95,7 +85,6 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state->state) {
|
if (!state->state) {
|
||||||
|
|
||||||
/* Setup compression context (very similar to the decoder) */
|
/* Setup compression context (very similar to the decoder) */
|
||||||
context->cinfo.err = jpeg_std_error(&context->error.pub);
|
context->cinfo.err = jpeg_std_error(&context->error.pub);
|
||||||
context->error.pub.error_exit = error;
|
context->error.pub.error_exit = error;
|
||||||
|
@ -106,7 +95,6 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
|
|
||||||
/* Ready to encode */
|
/* Ready to encode */
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the destination buffer */
|
/* Load the destination buffer */
|
||||||
|
@ -114,7 +102,6 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
context->destination.pub.free_in_buffer = bytes;
|
context->destination.pub.free_in_buffer = bytes;
|
||||||
|
|
||||||
switch (state->state) {
|
switch (state->state) {
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
|
||||||
context->cinfo.image_width = state->xsize;
|
context->cinfo.image_width = state->xsize;
|
||||||
|
@ -159,15 +146,20 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
quality = context->quality;
|
quality = context->quality;
|
||||||
}
|
}
|
||||||
for (i = 0; i < context->qtablesLen; i++) {
|
for (i = 0; i < context->qtablesLen; i++) {
|
||||||
jpeg_add_quant_table(&context->cinfo, i, &context->qtables[i * DCTSIZE2],
|
jpeg_add_quant_table(
|
||||||
quality, FALSE);
|
&context->cinfo,
|
||||||
|
i,
|
||||||
|
&context->qtables[i * DCTSIZE2],
|
||||||
|
quality,
|
||||||
|
FALSE);
|
||||||
context->cinfo.comp_info[i].quant_tbl_no = i;
|
context->cinfo.comp_info[i].quant_tbl_no = i;
|
||||||
last_q = i;
|
last_q = i;
|
||||||
}
|
}
|
||||||
if (context->qtablesLen == 1) {
|
if (context->qtablesLen == 1) {
|
||||||
// jpeg_set_defaults created two qtables internally, but we only wanted one.
|
// jpeg_set_defaults created two qtables internally, but we only
|
||||||
jpeg_add_quant_table(&context->cinfo, 1, &context->qtables[0],
|
// wanted one.
|
||||||
quality, FALSE);
|
jpeg_add_quant_table(
|
||||||
|
&context->cinfo, 1, &context->qtables[0], quality, FALSE);
|
||||||
}
|
}
|
||||||
for (i = last_q; i < context->cinfo.num_components; i++) {
|
for (i = last_q; i < context->cinfo.num_components; i++) {
|
||||||
context->cinfo.comp_info[i].quant_tbl_no = last_q;
|
context->cinfo.comp_info[i].quant_tbl_no = last_q;
|
||||||
|
@ -177,8 +169,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set subsampling options */
|
/* Set subsampling options */
|
||||||
switch (context->subsampling)
|
switch (context->subsampling) {
|
||||||
{
|
|
||||||
case 0: /* 1x1 1x1 1x1 (4:4:4) : None */
|
case 0: /* 1x1 1x1 1x1 (4:4:4) : None */
|
||||||
{
|
{
|
||||||
context->cinfo.comp_info[0].h_samp_factor = 1;
|
context->cinfo.comp_info[0].h_samp_factor = 1;
|
||||||
|
@ -209,8 +200,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
context->cinfo.comp_info[2].v_samp_factor = 1;
|
context->cinfo.comp_info[2].v_samp_factor = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default: {
|
||||||
{
|
|
||||||
/* Use the lib's default */
|
/* Use the lib's default */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -253,8 +243,11 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
// add exif header
|
// add exif header
|
||||||
if (context->rawExifLen > 0) {
|
if (context->rawExifLen > 0) {
|
||||||
jpeg_write_marker(&context->cinfo, JPEG_APP0+1,
|
jpeg_write_marker(
|
||||||
(unsigned char*)context->rawExif, context->rawExifLen);
|
&context->cinfo,
|
||||||
|
JPEG_APP0 + 1,
|
||||||
|
(unsigned char *)context->rawExif,
|
||||||
|
context->rawExifLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
state->state++;
|
state->state++;
|
||||||
|
@ -267,8 +260,10 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
if (n > context->destination.pub.free_in_buffer) {
|
if (n > context->destination.pub.free_in_buffer) {
|
||||||
n = context->destination.pub.free_in_buffer;
|
n = context->destination.pub.free_in_buffer;
|
||||||
}
|
}
|
||||||
memcpy(context->destination.pub.next_output_byte,
|
memcpy(
|
||||||
context->extra + context->extra_offset, n);
|
context->destination.pub.next_output_byte,
|
||||||
|
context->extra + context->extra_offset,
|
||||||
|
n);
|
||||||
context->destination.pub.next_output_byte += n;
|
context->destination.pub.next_output_byte += n;
|
||||||
context->destination.pub.free_in_buffer -= n;
|
context->destination.pub.free_in_buffer -= n;
|
||||||
context->extra_offset += n;
|
context->extra_offset += n;
|
||||||
|
@ -288,9 +283,11 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
|
|
||||||
ok = 1;
|
ok = 1;
|
||||||
while (state->y < state->ysize) {
|
while (state->y < state->ysize) {
|
||||||
state->shuffle(state->buffer,
|
state->shuffle(
|
||||||
|
state->buffer,
|
||||||
(UINT8 *)im->image[state->y + state->yoff] +
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
state->xoff * im->pixelsize, state->xsize);
|
state->xoff * im->pixelsize,
|
||||||
|
state->xsize);
|
||||||
ok = jpeg_write_scanlines(&context->cinfo, &state->buffer, 1);
|
ok = jpeg_write_scanlines(&context->cinfo, &state->buffer, 1);
|
||||||
if (ok != 1) {
|
if (ok != 1) {
|
||||||
break;
|
break;
|
||||||
|
@ -330,17 +327,14 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
/* if (jerr.pub.num_warnings) return BROKEN; */
|
/* if (jerr.pub.num_warnings) return BROKEN; */
|
||||||
state->errcode = IMAGING_CODEC_END;
|
state->errcode = IMAGING_CODEC_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return number of bytes in output buffer */
|
/* Return number of bytes in output buffer */
|
||||||
return context->destination.pub.next_output_byte - buf;
|
return context->destination.pub.next_output_byte - buf;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
ImagingJpegVersion(void)
|
ImagingJpegVersion(void) {
|
||||||
{
|
|
||||||
static char version[20];
|
static char version[20];
|
||||||
sprintf(version, "%d.%d", JPEG_LIB_VERSION / 10, JPEG_LIB_VERSION % 10);
|
sprintf(version, "%d.%d", JPEG_LIB_VERSION / 10, JPEG_LIB_VERSION % 10);
|
||||||
return version;
|
return version;
|
||||||
|
|
|
@ -13,16 +13,12 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
#define CLIPF(v) ((v <= 0.0) ? 0 : (v >= 255.0F) ? 255 : (UINT8)v)
|
#define CLIPF(v) ((v <= 0.0) ? 0 : (v >= 255.0F) ? 255 : (UINT8)v)
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingConvertMatrix(Imaging im, const char *mode, float m[])
|
ImagingConvertMatrix(Imaging im, const char *mode, float m[]) {
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
@ -32,7 +28,6 @@ ImagingConvertMatrix(Imaging im, const char *mode, float m[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(mode, "L") == 0 && im->bands == 3) {
|
if (strcmp(mode, "L") == 0 && im->bands == 3) {
|
||||||
|
|
||||||
imOut = ImagingNewDirty("L", im->xsize, im->ysize);
|
imOut = ImagingNewDirty("L", im->xsize, im->ysize);
|
||||||
if (!imOut) {
|
if (!imOut) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -50,7 +45,6 @@ ImagingConvertMatrix(Imaging im, const char *mode, float m[])
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (strlen(mode) == 3 && im->bands == 3) {
|
} else if (strlen(mode) == 3 && im->bands == 3) {
|
||||||
|
|
||||||
imOut = ImagingNewDirty(mode, im->xsize, im->ysize);
|
imOut = ImagingNewDirty(mode, im->xsize, im->ysize);
|
||||||
if (!imOut) {
|
if (!imOut) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -67,7 +61,8 @@ ImagingConvertMatrix(Imaging im, const char *mode, float m[])
|
||||||
out[0] = CLIPF(v0);
|
out[0] = CLIPF(v0);
|
||||||
out[1] = CLIPF(v1);
|
out[1] = CLIPF(v1);
|
||||||
out[2] = CLIPF(v2);
|
out[2] = CLIPF(v2);
|
||||||
in += 4; out += 4;
|
in += 4;
|
||||||
|
out += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingModeFilter(Imaging im, int size)
|
ImagingModeFilter(Imaging im, int size) {
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int x, y, i;
|
int x, y, i;
|
||||||
int xx, yy;
|
int xx, yy;
|
||||||
|
@ -39,7 +38,6 @@ ImagingModeFilter(Imaging im, int size)
|
||||||
for (y = 0; y < imOut->ysize; y++) {
|
for (y = 0; y < imOut->ysize; y++) {
|
||||||
UINT8 *out = &IMAGING_PIXEL_L(imOut, 0, y);
|
UINT8 *out = &IMAGING_PIXEL_L(imOut, 0, y);
|
||||||
for (x = 0; x < imOut->xsize; x++) {
|
for (x = 0; x < imOut->xsize; x++) {
|
||||||
|
|
||||||
/* calculate histogram over current area */
|
/* calculate histogram over current area */
|
||||||
|
|
||||||
/* FIXME: brute force! to improve, update the histogram
|
/* FIXME: brute force! to improve, update the histogram
|
||||||
|
@ -74,9 +72,7 @@ ImagingModeFilter(Imaging im, int size)
|
||||||
} else {
|
} else {
|
||||||
out[x] = IMAGING_PIXEL_L(im, x, y);
|
out[x] = IMAGING_PIXEL_L(im, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingCopyPalette(imOut, im);
|
ImagingCopyPalette(imOut, im);
|
||||||
|
|
|
@ -16,13 +16,10 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNegative(Imaging im)
|
ImagingNegative(Imaging im) {
|
||||||
{
|
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
@ -43,4 +40,3 @@ ImagingNegative(Imaging im)
|
||||||
|
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,10 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingOffset(Imaging im, int xoffset, int yoffset)
|
ImagingOffset(Imaging im, int xoffset, int yoffset) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#define R 0
|
#define R 0
|
||||||
|
@ -41,20 +40,28 @@
|
||||||
|
|
||||||
/* byte swapping macros */
|
/* byte swapping macros */
|
||||||
|
|
||||||
#define C16N\
|
#define C16N (out[0] = tmp[0], out[1] = tmp[1]);
|
||||||
(out[0]=tmp[0], out[1]=tmp[1]);
|
#define C16S (out[1] = tmp[0], out[0] = tmp[1]);
|
||||||
#define C16S\
|
#define C32N (out[0] = tmp[0], out[1] = tmp[1], out[2] = tmp[2], out[3] = tmp[3]);
|
||||||
(out[1]=tmp[0], out[0]=tmp[1]);
|
#define C32S (out[3] = tmp[0], out[2] = tmp[1], out[1] = tmp[2], out[0] = tmp[3]);
|
||||||
#define C32N\
|
|
||||||
(out[0]=tmp[0], out[1]=tmp[1], out[2]=tmp[2], out[3]=tmp[3]);
|
|
||||||
#define C32S\
|
|
||||||
(out[3]=tmp[0], out[2]=tmp[1], out[1]=tmp[2], out[0]=tmp[3]);
|
|
||||||
#define C64N \
|
#define C64N \
|
||||||
(out[0]=tmp[0], out[1]=tmp[1], out[2]=tmp[2], out[3]=tmp[3],\
|
(out[0] = tmp[0], \
|
||||||
out[4]=tmp[4], out[5]=tmp[5], out[6]=tmp[6], out[7]=tmp[7]);
|
out[1] = tmp[1], \
|
||||||
|
out[2] = tmp[2], \
|
||||||
|
out[3] = tmp[3], \
|
||||||
|
out[4] = tmp[4], \
|
||||||
|
out[5] = tmp[5], \
|
||||||
|
out[6] = tmp[6], \
|
||||||
|
out[7] = tmp[7]);
|
||||||
#define C64S \
|
#define C64S \
|
||||||
(out[7]=tmp[0], out[6]=tmp[1], out[5]=tmp[2], out[4]=tmp[3],\
|
(out[7] = tmp[0], \
|
||||||
out[3]=tmp[4], out[2]=tmp[5], out[1]=tmp[6], out[0]=tmp[7]);
|
out[6] = tmp[1], \
|
||||||
|
out[5] = tmp[2], \
|
||||||
|
out[4] = tmp[3], \
|
||||||
|
out[3] = tmp[4], \
|
||||||
|
out[2] = tmp[5], \
|
||||||
|
out[1] = tmp[6], \
|
||||||
|
out[0] = tmp[7]);
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
#define C16B C16N
|
#define C16B C16N
|
||||||
|
@ -72,13 +79,12 @@
|
||||||
#define C64L C64N
|
#define C64L C64N
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pack1(UINT8* out, const UINT8* in, int pixels)
|
pack1(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i, m, b;
|
int i, m, b;
|
||||||
/* bilevel (black is 0) */
|
/* bilevel (black is 0) */
|
||||||
b = 0; m = 128;
|
b = 0;
|
||||||
|
m = 128;
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
if (in[i] != 0) {
|
if (in[i] != 0) {
|
||||||
b |= m;
|
b |= m;
|
||||||
|
@ -86,7 +92,8 @@ pack1(UINT8* out, const UINT8* in, int pixels)
|
||||||
m >>= 1;
|
m >>= 1;
|
||||||
if (m == 0) {
|
if (m == 0) {
|
||||||
*out++ = b;
|
*out++ = b;
|
||||||
b = 0; m = 128;
|
b = 0;
|
||||||
|
m = 128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m != 128) {
|
if (m != 128) {
|
||||||
|
@ -95,11 +102,11 @@ pack1(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pack1I(UINT8* out, const UINT8* in, int pixels)
|
pack1I(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i, m, b;
|
int i, m, b;
|
||||||
/* bilevel (black is 1) */
|
/* bilevel (black is 1) */
|
||||||
b = 0; m = 128;
|
b = 0;
|
||||||
|
m = 128;
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
if (in[i] == 0) {
|
if (in[i] == 0) {
|
||||||
b |= m;
|
b |= m;
|
||||||
|
@ -107,7 +114,8 @@ pack1I(UINT8* out, const UINT8* in, int pixels)
|
||||||
m >>= 1;
|
m >>= 1;
|
||||||
if (m == 0) {
|
if (m == 0) {
|
||||||
*out++ = b;
|
*out++ = b;
|
||||||
b = 0; m = 128;
|
b = 0;
|
||||||
|
m = 128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m != 128) {
|
if (m != 128) {
|
||||||
|
@ -116,11 +124,11 @@ pack1I(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pack1R(UINT8* out, const UINT8* in, int pixels)
|
pack1R(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i, m, b;
|
int i, m, b;
|
||||||
/* bilevel, lsb first (black is 0) */
|
/* bilevel, lsb first (black is 0) */
|
||||||
b = 0; m = 1;
|
b = 0;
|
||||||
|
m = 1;
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
if (in[i] != 0) {
|
if (in[i] != 0) {
|
||||||
b |= m;
|
b |= m;
|
||||||
|
@ -128,7 +136,8 @@ pack1R(UINT8* out, const UINT8* in, int pixels)
|
||||||
m <<= 1;
|
m <<= 1;
|
||||||
if (m == 256) {
|
if (m == 256) {
|
||||||
*out++ = b;
|
*out++ = b;
|
||||||
b = 0; m = 1;
|
b = 0;
|
||||||
|
m = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m != 1) {
|
if (m != 1) {
|
||||||
|
@ -137,11 +146,11 @@ pack1R(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pack1IR(UINT8* out, const UINT8* in, int pixels)
|
pack1IR(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i, m, b;
|
int i, m, b;
|
||||||
/* bilevel, lsb first (black is 1) */
|
/* bilevel, lsb first (black is 1) */
|
||||||
b = 0; m = 1;
|
b = 0;
|
||||||
|
m = 1;
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
if (in[i] == 0) {
|
if (in[i] == 0) {
|
||||||
b |= m;
|
b |= m;
|
||||||
|
@ -149,7 +158,8 @@ pack1IR(UINT8* out, const UINT8* in, int pixels)
|
||||||
m <<= 1;
|
m <<= 1;
|
||||||
if (m == 256) {
|
if (m == 256) {
|
||||||
*out++ = b;
|
*out++ = b;
|
||||||
b = 0; m = 1;
|
b = 0;
|
||||||
|
m = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m != 1) {
|
if (m != 1) {
|
||||||
|
@ -158,8 +168,7 @@ pack1IR(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pack1L(UINT8* out, const UINT8* in, int pixels)
|
pack1L(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* bilevel, stored as bytes */
|
/* bilevel, stored as bytes */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -168,12 +177,11 @@ pack1L(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packP4(UINT8* out, const UINT8* in, int pixels)
|
packP4(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
while (pixels >= 2) {
|
while (pixels >= 2) {
|
||||||
*out++ = (in[0] << 4) |
|
*out++ = (in[0] << 4) | (in[1] & 15);
|
||||||
(in[1] & 15);
|
in += 2;
|
||||||
in += 2; pixels -= 2;
|
pixels -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pixels) {
|
if (pixels) {
|
||||||
|
@ -182,25 +190,19 @@ packP4(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packP2(UINT8* out, const UINT8* in, int pixels)
|
packP2(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
while (pixels >= 4) {
|
while (pixels >= 4) {
|
||||||
*out++ = (in[0] << 6) |
|
*out++ = (in[0] << 6) | ((in[1] & 3) << 4) | ((in[2] & 3) << 2) | (in[3] & 3);
|
||||||
((in[1] & 3) << 4) |
|
in += 4;
|
||||||
((in[2] & 3) << 2) |
|
pixels -= 4;
|
||||||
(in[3] & 3);
|
|
||||||
in += 4; pixels -= 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pixels) {
|
switch (pixels) {
|
||||||
case 3:
|
case 3:
|
||||||
out[0] = (in[0] << 6) |
|
out[0] = (in[0] << 6) | ((in[1] & 3) << 4) | ((in[2] & 3) << 2);
|
||||||
((in[1] & 3) << 4) |
|
|
||||||
((in[2] & 3) << 2);
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
out[0] = (in[0] << 6) |
|
out[0] = (in[0] << 6) | ((in[1] & 3) << 4);
|
||||||
((in[1] & 3) << 4);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
out[0] = (in[0] << 6);
|
out[0] = (in[0] << 6);
|
||||||
|
@ -208,8 +210,7 @@ packP2(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packL16(UINT8* out, const UINT8* in, int pixels)
|
packL16(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* L -> L;16, e.g: \xff77 -> \x00\xff\x00\x77 */
|
/* L -> L;16, e.g: \xff77 -> \x00\xff\x00\x77 */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -220,8 +221,7 @@ packL16(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packL16B(UINT8* out, const UINT8* in, int pixels)
|
packL16B(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* L -> L;16B, e.g: \xff77 -> \xff\x00\x77\x00 */
|
/* L -> L;16B, e.g: \xff77 -> \xff\x00\x77\x00 */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -231,22 +231,20 @@ packL16B(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packLA(UINT8* out, const UINT8* in, int pixels)
|
packLA(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* LA, pixel interleaved */
|
/* LA, pixel interleaved */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
out[0] = in[R];
|
out[0] = in[R];
|
||||||
out[1] = in[A];
|
out[1] = in[A];
|
||||||
out += 2; in += 4;
|
out += 2;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packLAL(UINT8* out, const UINT8* in, int pixels)
|
packLAL(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* LA, line interleaved */
|
/* LA, line interleaved */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -257,8 +255,7 @@ packLAL(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackRGB(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackRGB(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
/* RGB triplets */
|
/* RGB triplets */
|
||||||
#ifdef __sparc
|
#ifdef __sparc
|
||||||
|
@ -267,7 +264,8 @@ ImagingPackRGB(UINT8* out, const UINT8* in, int pixels)
|
||||||
out[0] = in[R];
|
out[0] = in[R];
|
||||||
out[1] = in[G];
|
out[1] = in[G];
|
||||||
out[2] = in[B];
|
out[2] = in[B];
|
||||||
out += 3; in += 4;
|
out += 3;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (; i < pixels - 1; i++) {
|
for (; i < pixels - 1; i++) {
|
||||||
|
@ -284,8 +282,7 @@ ImagingPackRGB(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackXRGB(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackXRGB(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* XRGB, triplets with left padding */
|
/* XRGB, triplets with left padding */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -293,26 +290,26 @@ ImagingPackXRGB(UINT8* out, const UINT8* in, int pixels)
|
||||||
out[1] = in[R];
|
out[1] = in[R];
|
||||||
out[2] = in[G];
|
out[2] = in[G];
|
||||||
out[3] = in[B];
|
out[3] = in[B];
|
||||||
out += 4; in += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackBGR(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackBGR(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* RGB, reversed bytes */
|
/* RGB, reversed bytes */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
out[0] = in[B];
|
out[0] = in[B];
|
||||||
out[1] = in[G];
|
out[1] = in[G];
|
||||||
out[2] = in[R];
|
out[2] = in[R];
|
||||||
out += 3; in += 4;
|
out += 3;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackBGRX(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackBGRX(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* BGRX, reversed bytes with right padding */
|
/* BGRX, reversed bytes with right padding */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -320,13 +317,13 @@ ImagingPackBGRX(UINT8* out, const UINT8* in, int pixels)
|
||||||
out[1] = in[G];
|
out[1] = in[G];
|
||||||
out[2] = in[R];
|
out[2] = in[R];
|
||||||
out[3] = 0;
|
out[3] = 0;
|
||||||
out += 4; in += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackXBGR(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackXBGR(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* XBGR, reversed bytes with left padding */
|
/* XBGR, reversed bytes with left padding */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -334,13 +331,13 @@ ImagingPackXBGR(UINT8* out, const UINT8* in, int pixels)
|
||||||
out[1] = in[B];
|
out[1] = in[B];
|
||||||
out[2] = in[G];
|
out[2] = in[G];
|
||||||
out[3] = in[R];
|
out[3] = in[R];
|
||||||
out += 4; in += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackBGRA(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackBGRA(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* BGRX, reversed bytes with right padding */
|
/* BGRX, reversed bytes with right padding */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -348,13 +345,13 @@ ImagingPackBGRA(UINT8* out, const UINT8* in, int pixels)
|
||||||
out[1] = in[G];
|
out[1] = in[G];
|
||||||
out[2] = in[R];
|
out[2] = in[R];
|
||||||
out[3] = in[A];
|
out[3] = in[A];
|
||||||
out += 4; in += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackABGR(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackABGR(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* XBGR, reversed bytes with left padding */
|
/* XBGR, reversed bytes with left padding */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -362,13 +359,13 @@ ImagingPackABGR(UINT8* out, const UINT8* in, int pixels)
|
||||||
out[1] = in[B];
|
out[1] = in[B];
|
||||||
out[2] = in[G];
|
out[2] = in[G];
|
||||||
out[3] = in[R];
|
out[3] = in[R];
|
||||||
out += 4; in += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackBGRa(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackBGRa(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* BGRa, reversed bytes with premultiplied alpha */
|
/* BGRa, reversed bytes with premultiplied alpha */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -377,13 +374,13 @@ ImagingPackBGRa(UINT8* out, const UINT8* in, int pixels)
|
||||||
out[0] = MULDIV255(in[B], alpha, tmp);
|
out[0] = MULDIV255(in[B], alpha, tmp);
|
||||||
out[1] = MULDIV255(in[G], alpha, tmp);
|
out[1] = MULDIV255(in[G], alpha, tmp);
|
||||||
out[2] = MULDIV255(in[R], alpha, tmp);
|
out[2] = MULDIV255(in[R], alpha, tmp);
|
||||||
out += 4; in += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packRGBL(UINT8* out, const UINT8* in, int pixels)
|
packRGBL(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* RGB, line interleaved */
|
/* RGB, line interleaved */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -395,8 +392,7 @@ packRGBL(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packRGBXL(UINT8* out, const UINT8* in, int pixels)
|
packRGBXL(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* RGBX, line interleaved */
|
/* RGBX, line interleaved */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -409,8 +405,7 @@ packRGBXL(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packI16B(UINT8* out, const UINT8* in_, int pixels)
|
packI16B(UINT8 *out, const UINT8 *in_, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
UINT16 tmp_;
|
UINT16 tmp_;
|
||||||
UINT8 *tmp = (UINT8 *)&tmp_;
|
UINT8 *tmp = (UINT8 *)&tmp_;
|
||||||
|
@ -425,7 +420,8 @@ packI16B(UINT8* out, const UINT8* in_, int pixels)
|
||||||
tmp_ = in;
|
tmp_ = in;
|
||||||
}
|
}
|
||||||
C16B;
|
C16B;
|
||||||
out += 2; in_ += sizeof(in);
|
out += 2;
|
||||||
|
in_ += sizeof(in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,9 +431,9 @@ packI16N_I16B(UINT8* out, const UINT8* in, int pixels){
|
||||||
UINT8 *tmp = (UINT8 *)in;
|
UINT8 *tmp = (UINT8 *)in;
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
C16B;
|
C16B;
|
||||||
out += 2; tmp += 2;
|
out += 2;
|
||||||
|
tmp += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
packI16N_I16(UINT8 *out, const UINT8 *in, int pixels) {
|
packI16N_I16(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
|
@ -445,66 +441,61 @@ packI16N_I16(UINT8* out, const UINT8* in, int pixels){
|
||||||
UINT8 *tmp = (UINT8 *)in;
|
UINT8 *tmp = (UINT8 *)in;
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
C16L;
|
C16L;
|
||||||
out += 2; tmp += 2;
|
out += 2;
|
||||||
|
tmp += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
packI32S(UINT8* out, const UINT8* in, int pixels)
|
packI32S(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
UINT8 *tmp = (UINT8 *)in;
|
UINT8 *tmp = (UINT8 *)in;
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
C32L;
|
C32L;
|
||||||
out += 4; tmp += 4;
|
out += 4;
|
||||||
|
tmp += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPackLAB(UINT8* out, const UINT8* in, int pixels)
|
ImagingPackLAB(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* LAB triplets */
|
/* LAB triplets */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
out[0] = in[0];
|
out[0] = in[0];
|
||||||
out[1] = in[1] ^ 128; /* signed in outside world */
|
out[1] = in[1] ^ 128; /* signed in outside world */
|
||||||
out[2] = in[2] ^ 128;
|
out[2] = in[2] ^ 128;
|
||||||
out += 3; in += 4;
|
out += 3;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy1(UINT8* out, const UINT8* in, int pixels)
|
copy1(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
/* L, P */
|
/* L, P */
|
||||||
memcpy(out, in, pixels);
|
memcpy(out, in, pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy2(UINT8* out, const UINT8* in, int pixels)
|
copy2(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
/* I;16, etc */
|
/* I;16, etc */
|
||||||
memcpy(out, in, pixels * 2);
|
memcpy(out, in, pixels * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy3(UINT8* out, const UINT8* in, int pixels)
|
copy3(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
/* BGR;24, etc */
|
/* BGR;24, etc */
|
||||||
memcpy(out, in, pixels * 3);
|
memcpy(out, in, pixels * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy4(UINT8* out, const UINT8* in, int pixels)
|
copy4(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
/* RGBA, CMYK quadruples */
|
/* RGBA, CMYK quadruples */
|
||||||
memcpy(out, in, 4 * pixels);
|
memcpy(out, in, 4 * pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy4I(UINT8* out, const UINT8* in, int pixels)
|
copy4I(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
/* RGBA, CMYK quadruples, inverted */
|
/* RGBA, CMYK quadruples, inverted */
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < pixels * 4; i++) {
|
for (i = 0; i < pixels * 4; i++) {
|
||||||
|
@ -513,8 +504,7 @@ copy4I(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
band0(UINT8* out, const UINT8* in, int pixels)
|
band0(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < pixels; i++, in += 4) {
|
for (i = 0; i < pixels; i++, in += 4) {
|
||||||
out[i] = in[0];
|
out[i] = in[0];
|
||||||
|
@ -522,8 +512,7 @@ band0(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
band1(UINT8* out, const UINT8* in, int pixels)
|
band1(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < pixels; i++, in += 4) {
|
for (i = 0; i < pixels; i++, in += 4) {
|
||||||
out[i] = in[1];
|
out[i] = in[1];
|
||||||
|
@ -531,8 +520,7 @@ band1(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
band2(UINT8* out, const UINT8* in, int pixels)
|
band2(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < pixels; i++, in += 4) {
|
for (i = 0; i < pixels; i++, in += 4) {
|
||||||
out[i] = in[2];
|
out[i] = in[2];
|
||||||
|
@ -540,8 +528,7 @@ band2(UINT8* out, const UINT8* in, int pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
band3(UINT8* out, const UINT8* in, int pixels)
|
band3(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < pixels; i++, in += 4) {
|
for (i = 0; i < pixels; i++, in += 4) {
|
||||||
out[i] = in[3];
|
out[i] = in[3];
|
||||||
|
@ -682,10 +669,8 @@ static struct {
|
||||||
{NULL} /* sentinel */
|
{NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ImagingShuffler
|
ImagingShuffler
|
||||||
ImagingFindPacker(const char* mode, const char* rawmode, int* bits_out)
|
ImagingFindPacker(const char *mode, const char *rawmode, int *bits_out) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* find a suitable pixel packer */
|
/* find a suitable pixel packer */
|
||||||
|
|
|
@ -13,13 +13,11 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
|
ImagingPackbitsDecode(
|
||||||
UINT8* buf, Py_ssize_t bytes)
|
Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
UINT8 n;
|
UINT8 n;
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
int i;
|
int i;
|
||||||
|
@ -27,16 +25,15 @@ ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (bytes < 1) {
|
if (bytes < 1) {
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr[0] & 0x80) {
|
if (ptr[0] & 0x80) {
|
||||||
|
|
||||||
if (ptr[0] == 0x80) {
|
if (ptr[0] == 0x80) {
|
||||||
/* Nop */
|
/* Nop */
|
||||||
ptr++; bytes--;
|
ptr++;
|
||||||
|
bytes--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,10 +50,10 @@ ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
|
||||||
state->buffer[state->x++] = ptr[1];
|
state->buffer[state->x++] = ptr[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += 2; bytes -= 2;
|
ptr += 2;
|
||||||
|
bytes -= 2;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Literal */
|
/* Literal */
|
||||||
n = ptr[0] + 2;
|
n = ptr[0] + 2;
|
||||||
|
|
||||||
|
@ -72,15 +69,16 @@ ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
|
||||||
state->buffer[state->x++] = ptr[i];
|
state->buffer[state->x++] = ptr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += n; bytes -= n;
|
ptr += n;
|
||||||
|
bytes -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->x >= state->bytes) {
|
if (state->x >= state->bytes) {
|
||||||
|
|
||||||
/* Got a full line, unpack it */
|
/* Got a full line, unpack it */
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
state->shuffle(
|
||||||
state->xoff * im->pixelsize, state->buffer,
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
|
state->xoff * im->pixelsize,
|
||||||
|
state->buffer,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
|
||||||
state->x = 0;
|
state->x = 0;
|
||||||
|
@ -90,6 +88,5 @@ ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,12 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
ImagingPalette
|
ImagingPalette
|
||||||
ImagingPaletteNew(const char* mode)
|
ImagingPaletteNew(const char *mode) {
|
||||||
{
|
|
||||||
/* Create a palette object */
|
/* Create a palette object */
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
@ -44,8 +41,7 @@ ImagingPaletteNew(const char* mode)
|
||||||
|
|
||||||
/* Initialize to ramp */
|
/* Initialize to ramp */
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
palette->palette[i*4+0] =
|
palette->palette[i * 4 + 0] = palette->palette[i * 4 + 1] =
|
||||||
palette->palette[i*4+1] =
|
|
||||||
palette->palette[i * 4 + 2] = (UINT8)i;
|
palette->palette[i * 4 + 2] = (UINT8)i;
|
||||||
palette->palette[i * 4 + 3] = 255; /* opaque */
|
palette->palette[i * 4 + 3] = 255; /* opaque */
|
||||||
}
|
}
|
||||||
|
@ -54,8 +50,7 @@ ImagingPaletteNew(const char* mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingPalette
|
ImagingPalette
|
||||||
ImagingPaletteNewBrowser(void)
|
ImagingPaletteNewBrowser(void) {
|
||||||
{
|
|
||||||
/* Create a standard "browser" palette object */
|
/* Create a standard "browser" palette object */
|
||||||
|
|
||||||
int i, r, g, b;
|
int i, r, g, b;
|
||||||
|
@ -70,8 +65,7 @@ ImagingPaletteNewBrowser(void)
|
||||||
/* FIXME: Add 10-level windows palette here? */
|
/* FIXME: Add 10-level windows palette here? */
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
palette->palette[i*4+0] =
|
palette->palette[i * 4 + 0] = palette->palette[i * 4 + 1] =
|
||||||
palette->palette[i*4+1] =
|
|
||||||
palette->palette[i * 4 + 2] = 0;
|
palette->palette[i * 4 + 2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +86,7 @@ ImagingPaletteNewBrowser(void)
|
||||||
/* FIXME: add 30-level greyscale wedge here? */
|
/* FIXME: add 30-level greyscale wedge here? */
|
||||||
|
|
||||||
for (; i < 256; i++) {
|
for (; i < 256; i++) {
|
||||||
palette->palette[i*4+0] =
|
palette->palette[i * 4 + 0] = palette->palette[i * 4 + 1] =
|
||||||
palette->palette[i*4+1] =
|
|
||||||
palette->palette[i * 4 + 2] = 0;
|
palette->palette[i * 4 + 2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +94,7 @@ ImagingPaletteNewBrowser(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingPalette
|
ImagingPalette
|
||||||
ImagingPaletteDuplicate(ImagingPalette palette)
|
ImagingPaletteDuplicate(ImagingPalette palette) {
|
||||||
{
|
|
||||||
/* Duplicate palette descriptor */
|
/* Duplicate palette descriptor */
|
||||||
|
|
||||||
ImagingPalette new_palette;
|
ImagingPalette new_palette;
|
||||||
|
@ -125,8 +117,7 @@ ImagingPaletteDuplicate(ImagingPalette palette)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPaletteDelete(ImagingPalette palette)
|
ImagingPaletteDelete(ImagingPalette palette) {
|
||||||
{
|
|
||||||
/* Destroy palette object */
|
/* Destroy palette object */
|
||||||
|
|
||||||
if (palette) {
|
if (palette) {
|
||||||
|
@ -137,7 +128,6 @@ ImagingPaletteDelete(ImagingPalette palette)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Colour mapping */
|
/* Colour mapping */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -174,8 +164,7 @@ ImagingPaletteDelete(ImagingPalette palette)
|
||||||
#define BOXVOLUME BOX *BOX *BOX
|
#define BOXVOLUME BOX *BOX *BOX
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
|
ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b) {
|
||||||
{
|
|
||||||
int i, j;
|
int i, j;
|
||||||
unsigned int dmin[256], dmax;
|
unsigned int dmin[256], dmax;
|
||||||
int r0, g0, b0;
|
int r0, g0, b0;
|
||||||
|
@ -187,9 +176,15 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
|
||||||
/* Get box boundaries for the given (r,g,b)-triplet. Each box
|
/* Get box boundaries for the given (r,g,b)-triplet. Each box
|
||||||
covers eight cache slots (32 colour values, that is). */
|
covers eight cache slots (32 colour values, that is). */
|
||||||
|
|
||||||
r0 = r & 0xe0; r1 = r0 + 0x1f; rc = (r0 + r1) / 2;
|
r0 = r & 0xe0;
|
||||||
g0 = g & 0xe0; g1 = g0 + 0x1f; gc = (g0 + g1) / 2;
|
r1 = r0 + 0x1f;
|
||||||
b0 = b & 0xe0; b1 = b0 + 0x1f; bc = (b0 + b1) / 2;
|
rc = (r0 + r1) / 2;
|
||||||
|
g0 = g & 0xe0;
|
||||||
|
g1 = g0 + 0x1f;
|
||||||
|
gc = (g0 + g1) / 2;
|
||||||
|
b0 = b & 0xe0;
|
||||||
|
b1 = b0 + 0x1f;
|
||||||
|
bc = (b0 + b1) / 2;
|
||||||
|
|
||||||
/* Step 1 -- Select relevant palette entries (after Heckbert) */
|
/* Step 1 -- Select relevant palette entries (after Heckbert) */
|
||||||
|
|
||||||
|
@ -199,7 +194,6 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
|
||||||
dmax = (unsigned int)~0;
|
dmax = (unsigned int)~0;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
|
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
unsigned int tmin, tmax;
|
unsigned int tmin, tmax;
|
||||||
|
|
||||||
|
@ -220,7 +214,6 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
|
||||||
if (tmax < dmax) {
|
if (tmax < dmax) {
|
||||||
dmax = tmax; /* keep the smallest max distance only */
|
dmax = tmax; /* keep the smallest max distance only */
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 2 -- Incrementally update cache slot (after Thomas) */
|
/* Step 2 -- Incrementally update cache slot (after Thomas) */
|
||||||
|
@ -234,9 +227,7 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
|
|
||||||
if (dmin[i] <= dmax) {
|
if (dmin[i] <= dmax) {
|
||||||
|
|
||||||
int rd, gd, bd;
|
int rd, gd, bd;
|
||||||
int ri, gi, bi;
|
int ri, gi, bi;
|
||||||
int rx, gx, bx;
|
int rx, gx, bx;
|
||||||
|
@ -253,9 +244,11 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
|
||||||
|
|
||||||
rx = ri;
|
rx = ri;
|
||||||
for (r = j = 0; r < BOX; r++) {
|
for (r = j = 0; r < BOX; r++) {
|
||||||
gd = rd; gx = gi;
|
gd = rd;
|
||||||
|
gx = gi;
|
||||||
for (g = 0; g < BOX; g++) {
|
for (g = 0; g < BOX; g++) {
|
||||||
bd = gd; bx = bi;
|
bd = gd;
|
||||||
|
bx = bi;
|
||||||
for (b = 0; b < BOX; b++) {
|
for (b = 0; b < BOX; b++) {
|
||||||
if ((unsigned int)bd < d[j]) {
|
if ((unsigned int)bd < d[j]) {
|
||||||
d[j] = bd;
|
d[j] = bd;
|
||||||
|
@ -289,17 +282,14 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingPaletteCachePrepare(ImagingPalette palette)
|
ImagingPaletteCachePrepare(ImagingPalette palette) {
|
||||||
{
|
|
||||||
/* Add a colour cache to a palette */
|
/* Add a colour cache to a palette */
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int entries = 64 * 64 * 64;
|
int entries = 64 * 64 * 64;
|
||||||
|
|
||||||
if (palette->cache == NULL) {
|
if (palette->cache == NULL) {
|
||||||
|
|
||||||
/* The cache is 512k. It might be a good idea to break it
|
/* The cache is 512k. It might be a good idea to break it
|
||||||
up into a pointer array (e.g. an 8-bit image?) */
|
up into a pointer array (e.g. an 8-bit image?) */
|
||||||
|
|
||||||
|
@ -314,16 +304,13 @@ ImagingPaletteCachePrepare(ImagingPalette palette)
|
||||||
for (i = 0; i < entries; i++) {
|
for (i = 0; i < entries; i++) {
|
||||||
palette->cache[i] = 0x100;
|
palette->cache[i] = 0x100;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingPaletteCacheDelete(ImagingPalette palette)
|
ImagingPaletteCacheDelete(ImagingPalette palette) {
|
||||||
{
|
|
||||||
/* Release the colour cache, if any */
|
/* Release the colour cache, if any */
|
||||||
|
|
||||||
if (palette && palette->cache) {
|
if (palette && palette->cache) {
|
||||||
|
|
|
@ -23,11 +23,17 @@
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
paste(Imaging imOut, Imaging imIn, int dx, int dy, int sx, int sy,
|
paste(
|
||||||
int xsize, int ysize, int pixelsize)
|
Imaging imOut,
|
||||||
{
|
Imaging imIn,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* paste opaque region */
|
/* paste opaque region */
|
||||||
|
|
||||||
int y;
|
int y;
|
||||||
|
@ -43,16 +49,22 @@ paste(Imaging imOut, Imaging imIn, int dx, int dy, int sx, int sy,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
paste_mask_1(Imaging imOut, Imaging imIn, Imaging imMask,
|
paste_mask_1(
|
||||||
int dx, int dy, int sx, int sy,
|
Imaging imOut,
|
||||||
int xsize, int ysize, int pixelsize)
|
Imaging imIn,
|
||||||
{
|
Imaging imMask,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* paste with mode "1" mask */
|
/* paste with mode "1" mask */
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *in = imIn->image8[y + sy] + sx;
|
UINT8 *in = imIn->image8[y + sy] + sx;
|
||||||
|
@ -66,7 +78,6 @@ paste_mask_1(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
INT32 *out = imOut->image32[y + dy] + dx;
|
INT32 *out = imOut->image32[y + dy] + dx;
|
||||||
INT32 *in = imIn->image32[y + sy] + sx;
|
INT32 *in = imIn->image32[y + sy] + sx;
|
||||||
|
@ -82,17 +93,23 @@ paste_mask_1(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
paste_mask_L(Imaging imOut, Imaging imIn, Imaging imMask,
|
paste_mask_L(
|
||||||
int dx, int dy, int sx, int sy,
|
Imaging imOut,
|
||||||
int xsize, int ysize, int pixelsize)
|
Imaging imIn,
|
||||||
{
|
Imaging imMask,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* paste with mode "L" matte */
|
/* paste with mode "L" matte */
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *in = imIn->image8[y + sy] + sx;
|
UINT8 *in = imIn->image8[y + sy] + sx;
|
||||||
|
@ -104,7 +121,6 @@ paste_mask_L(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
||||||
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
||||||
|
@ -115,24 +131,32 @@ paste_mask_L(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
out[1] = BLEND(a, out[1], in[1], tmp1);
|
out[1] = BLEND(a, out[1], in[1], tmp1);
|
||||||
out[2] = BLEND(a, out[2], in[2], tmp1);
|
out[2] = BLEND(a, out[2], in[2], tmp1);
|
||||||
out[3] = BLEND(a, out[3], in[3], tmp1);
|
out[3] = BLEND(a, out[3], in[3], tmp1);
|
||||||
out += 4; in += 4; mask ++;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
|
mask++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
paste_mask_RGBA(Imaging imOut, Imaging imIn, Imaging imMask,
|
paste_mask_RGBA(
|
||||||
int dx, int dy, int sx, int sy,
|
Imaging imOut,
|
||||||
int xsize, int ysize, int pixelsize)
|
Imaging imIn,
|
||||||
{
|
Imaging imMask,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* paste with mode "RGBA" matte */
|
/* paste with mode "RGBA" matte */
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *in = imIn->image8[y + sy] + sx;
|
UINT8 *in = imIn->image8[y + sy] + sx;
|
||||||
|
@ -144,7 +168,6 @@ paste_mask_RGBA(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
||||||
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
||||||
|
@ -155,25 +178,32 @@ paste_mask_RGBA(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
out[1] = BLEND(a, out[1], in[1], tmp1);
|
out[1] = BLEND(a, out[1], in[1], tmp1);
|
||||||
out[2] = BLEND(a, out[2], in[2], tmp1);
|
out[2] = BLEND(a, out[2], in[2], tmp1);
|
||||||
out[3] = BLEND(a, out[3], in[3], tmp1);
|
out[3] = BLEND(a, out[3], in[3], tmp1);
|
||||||
out += 4; in += 4; mask += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
|
mask += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
paste_mask_RGBa(Imaging imOut, Imaging imIn, Imaging imMask,
|
paste_mask_RGBa(
|
||||||
int dx, int dy, int sx, int sy,
|
Imaging imOut,
|
||||||
int xsize, int ysize, int pixelsize)
|
Imaging imIn,
|
||||||
{
|
Imaging imMask,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* paste with mode "RGBa" matte */
|
/* paste with mode "RGBa" matte */
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *in = imIn->image8[y + sy] + sx;
|
UINT8 *in = imIn->image8[y + sy] + sx;
|
||||||
|
@ -185,7 +215,6 @@ paste_mask_RGBa(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
||||||
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
||||||
|
@ -196,16 +225,17 @@ paste_mask_RGBa(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
out[1] = PREBLEND(a, out[1], in[1], tmp1);
|
out[1] = PREBLEND(a, out[1], in[1], tmp1);
|
||||||
out[2] = PREBLEND(a, out[2], in[2], tmp1);
|
out[2] = PREBLEND(a, out[2], in[2], tmp1);
|
||||||
out[3] = PREBLEND(a, out[3], in[3], tmp1);
|
out[3] = PREBLEND(a, out[3], in[3], tmp1);
|
||||||
out += 4; in += 4; mask += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
|
mask += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingPaste(Imaging imOut, Imaging imIn, Imaging imMask,
|
ImagingPaste(
|
||||||
int dx0, int dy0, int dx1, int dy1)
|
Imaging imOut, Imaging imIn, Imaging imMask, int dx0, int dy0, int dx1, int dy1) {
|
||||||
{
|
|
||||||
int xsize, ysize;
|
int xsize, ysize;
|
||||||
int pixelsize;
|
int pixelsize;
|
||||||
int sx0, sy0;
|
int sx0, sy0;
|
||||||
|
@ -221,8 +251,7 @@ ImagingPaste(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
xsize = dx1 - dx0;
|
xsize = dx1 - dx0;
|
||||||
ysize = dy1 - dy0;
|
ysize = dy1 - dy0;
|
||||||
|
|
||||||
if (xsize != imIn->xsize || ysize != imIn->ysize ||
|
if (xsize != imIn->xsize || ysize != imIn->ysize || pixelsize != imIn->pixelsize) {
|
||||||
pixelsize != imIn->pixelsize) {
|
|
||||||
(void)ImagingError_Mismatch();
|
(void)ImagingError_Mismatch();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -258,26 +287,24 @@ ImagingPaste(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "1") == 0) {
|
} else if (strcmp(imMask->mode, "1") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
paste_mask_1(imOut, imIn, imMask, dx0, dy0, sx0, sy0,
|
paste_mask_1(imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
xsize, ysize, pixelsize);
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "L") == 0) {
|
} else if (strcmp(imMask->mode, "L") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0,
|
paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
xsize, ysize, pixelsize);
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "RGBA") == 0) {
|
} else if (strcmp(imMask->mode, "RGBA") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
paste_mask_RGBA(imOut, imIn, imMask, dx0, dy0, sx0, sy0,
|
paste_mask_RGBA(
|
||||||
xsize, ysize, pixelsize);
|
imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "RGBa") == 0) {
|
} else if (strcmp(imMask->mode, "RGBa") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
paste_mask_RGBa(imOut, imIn, imMask, dx0, dy0, sx0, sy0,
|
paste_mask_RGBa(
|
||||||
xsize, ysize, pixelsize);
|
imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -289,9 +316,14 @@ ImagingPaste(Imaging imOut, Imaging imIn, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fill(Imaging imOut, const void* ink_, int dx, int dy,
|
fill(
|
||||||
int xsize, int ysize, int pixelsize)
|
Imaging imOut,
|
||||||
{
|
const void *ink_,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* fill opaque region */
|
/* fill opaque region */
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -302,7 +334,6 @@ fill(Imaging imOut, const void* ink_, int dx, int dy,
|
||||||
memcpy(&ink8, ink_, sizeof(ink8));
|
memcpy(&ink8, ink_, sizeof(ink8));
|
||||||
|
|
||||||
if (imOut->image8 || ink32 == 0L) {
|
if (imOut->image8 || ink32 == 0L) {
|
||||||
|
|
||||||
dx *= pixelsize;
|
dx *= pixelsize;
|
||||||
xsize *= pixelsize;
|
xsize *= pixelsize;
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
|
@ -310,22 +341,27 @@ fill(Imaging imOut, const void* ink_, int dx, int dy,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
INT32 *out = imOut->image32[y + dy] + dx;
|
INT32 *out = imOut->image32[y + dy] + dx;
|
||||||
for (x = 0; x < xsize; x++) {
|
for (x = 0; x < xsize; x++) {
|
||||||
out[x] = ink32;
|
out[x] = ink32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fill_mask_1(Imaging imOut, const void* ink_, Imaging imMask,
|
fill_mask_1(
|
||||||
int dx, int dy, int sx, int sy,
|
Imaging imOut,
|
||||||
int xsize, int ysize, int pixelsize)
|
const void *ink_,
|
||||||
{
|
Imaging imMask,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* fill with mode "1" mask */
|
/* fill with mode "1" mask */
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -336,7 +372,6 @@ fill_mask_1(Imaging imOut, const void* ink_, Imaging imMask,
|
||||||
memcpy(&ink8, ink_, sizeof(ink8));
|
memcpy(&ink8, ink_, sizeof(ink8));
|
||||||
|
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *mask = imMask->image8[y + sy] + sx;
|
UINT8 *mask = imMask->image8[y + sy] + sx;
|
||||||
|
@ -349,7 +384,6 @@ fill_mask_1(Imaging imOut, const void* ink_, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
INT32 *out = imOut->image32[y + dy] + dx;
|
INT32 *out = imOut->image32[y + dy] + dx;
|
||||||
UINT8 *mask = imMask->image8[y + sy] + sx;
|
UINT8 *mask = imMask->image8[y + sy] + sx;
|
||||||
|
@ -364,17 +398,23 @@ fill_mask_1(Imaging imOut, const void* ink_, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fill_mask_L(Imaging imOut, const UINT8* ink, Imaging imMask,
|
fill_mask_L(
|
||||||
int dx, int dy, int sx, int sy,
|
Imaging imOut,
|
||||||
int xsize, int ysize, int pixelsize)
|
const UINT8 *ink,
|
||||||
{
|
Imaging imMask,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* fill with mode "L" matte */
|
/* fill with mode "L" matte */
|
||||||
|
|
||||||
int x, y, i;
|
int x, y, i;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *mask = imMask->image8[y + sy] + sx;
|
UINT8 *mask = imMask->image8[y + sy] + sx;
|
||||||
|
@ -385,21 +425,20 @@ fill_mask_L(Imaging imOut, const UINT8* ink, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = (UINT8 *)imOut->image[y + dy] + dx * pixelsize;
|
UINT8 *out = (UINT8 *)imOut->image[y + dy] + dx * pixelsize;
|
||||||
UINT8 *mask = (UINT8 *)imMask->image[y + sy] + sx;
|
UINT8 *mask = (UINT8 *)imMask->image[y + sy] + sx;
|
||||||
for (x = 0; x < xsize; x++) {
|
for (x = 0; x < xsize; x++) {
|
||||||
for (i = 0; i < pixelsize; i++) {
|
for (i = 0; i < pixelsize; i++) {
|
||||||
UINT8 channel_mask = *mask;
|
UINT8 channel_mask = *mask;
|
||||||
if ((
|
if ((strcmp(imOut->mode, "RGBa") == 0 ||
|
||||||
strcmp(imOut->mode, "RGBa") == 0 ||
|
|
||||||
strcmp(imOut->mode, "RGBA") == 0 ||
|
strcmp(imOut->mode, "RGBA") == 0 ||
|
||||||
strcmp(imOut->mode, "La") == 0 ||
|
strcmp(imOut->mode, "La") == 0 ||
|
||||||
strcmp(imOut->mode, "LA") == 0 ||
|
strcmp(imOut->mode, "LA") == 0 ||
|
||||||
strcmp(imOut->mode, "PA") == 0
|
strcmp(imOut->mode, "PA") == 0) &&
|
||||||
) && i != 3) {
|
i != 3) {
|
||||||
channel_mask = 255 - (255 - channel_mask) * (1 - (255 - out[3]) / 255);
|
channel_mask =
|
||||||
|
255 - (255 - channel_mask) * (1 - (255 - out[3]) / 255);
|
||||||
}
|
}
|
||||||
out[i] = BLEND(channel_mask, out[i], ink[i], tmp1);
|
out[i] = BLEND(channel_mask, out[i], ink[i], tmp1);
|
||||||
}
|
}
|
||||||
|
@ -411,17 +450,23 @@ fill_mask_L(Imaging imOut, const UINT8* ink, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fill_mask_RGBA(Imaging imOut, const UINT8* ink, Imaging imMask,
|
fill_mask_RGBA(
|
||||||
int dx, int dy, int sx, int sy,
|
Imaging imOut,
|
||||||
int xsize, int ysize, int pixelsize)
|
const UINT8 *ink,
|
||||||
{
|
Imaging imMask,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* fill with mode "RGBA" matte */
|
/* fill with mode "RGBA" matte */
|
||||||
|
|
||||||
int x, y, i;
|
int x, y, i;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
|
|
||||||
sx = sx * 4 + 3;
|
sx = sx * 4 + 3;
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
|
@ -433,7 +478,6 @@ fill_mask_RGBA(Imaging imOut, const UINT8* ink, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
dx *= pixelsize;
|
dx *= pixelsize;
|
||||||
sx = sx * 4 + 3;
|
sx = sx * 4 + 3;
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
|
@ -451,17 +495,23 @@ fill_mask_RGBA(Imaging imOut, const UINT8* ink, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fill_mask_RGBa(Imaging imOut, const UINT8* ink, Imaging imMask,
|
fill_mask_RGBa(
|
||||||
int dx, int dy, int sx, int sy,
|
Imaging imOut,
|
||||||
int xsize, int ysize, int pixelsize)
|
const UINT8 *ink,
|
||||||
{
|
Imaging imMask,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
int sx,
|
||||||
|
int sy,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
int pixelsize) {
|
||||||
/* fill with mode "RGBa" matte */
|
/* fill with mode "RGBa" matte */
|
||||||
|
|
||||||
int x, y, i;
|
int x, y, i;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
|
|
||||||
sx = sx * 4 + 3;
|
sx = sx * 4 + 3;
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
|
@ -473,7 +523,6 @@ fill_mask_RGBa(Imaging imOut, const UINT8* ink, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
dx *= pixelsize;
|
dx *= pixelsize;
|
||||||
sx = sx * 4 + 3;
|
sx = sx * 4 + 3;
|
||||||
for (y = 0; y < ysize; y++) {
|
for (y = 0; y < ysize; y++) {
|
||||||
|
@ -491,9 +540,14 @@ fill_mask_RGBa(Imaging imOut, const UINT8* ink, Imaging imMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingFill2(Imaging imOut, const void* ink, Imaging imMask,
|
ImagingFill2(
|
||||||
int dx0, int dy0, int dx1, int dy1)
|
Imaging imOut,
|
||||||
{
|
const void *ink,
|
||||||
|
Imaging imMask,
|
||||||
|
int dx0,
|
||||||
|
int dy0,
|
||||||
|
int dx1,
|
||||||
|
int dy1) {
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int xsize, ysize;
|
int xsize, ysize;
|
||||||
int pixelsize;
|
int pixelsize;
|
||||||
|
@ -540,26 +594,22 @@ ImagingFill2(Imaging imOut, const void* ink, Imaging imMask,
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "1") == 0) {
|
} else if (strcmp(imMask->mode, "1") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
fill_mask_1(imOut, ink, imMask, dx0, dy0, sx0, sy0,
|
fill_mask_1(imOut, ink, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
xsize, ysize, pixelsize);
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "L") == 0) {
|
} else if (strcmp(imMask->mode, "L") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
fill_mask_L(imOut, ink, imMask, dx0, dy0, sx0, sy0,
|
fill_mask_L(imOut, ink, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
xsize, ysize, pixelsize);
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "RGBA") == 0) {
|
} else if (strcmp(imMask->mode, "RGBA") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
fill_mask_RGBA(imOut, ink, imMask, dx0, dy0, sx0, sy0,
|
fill_mask_RGBA(imOut, ink, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
xsize, ysize, pixelsize);
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "RGBa") == 0) {
|
} else if (strcmp(imMask->mode, "RGBa") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
fill_mask_RGBa(imOut, ink, imMask, dx0, dy0, sx0, sy0,
|
fill_mask_RGBa(imOut, ink, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
xsize, ysize, pixelsize);
|
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -19,13 +19,10 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
int x;
|
int x;
|
||||||
int chunk;
|
int chunk;
|
||||||
UINT8 *out;
|
UINT8 *out;
|
||||||
|
@ -36,7 +33,6 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
chunk = 3 * state->xsize;
|
chunk = 3 * state->xsize;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
/* We need data for two full lines before we can do anything */
|
/* We need data for two full lines before we can do anything */
|
||||||
if (bytes < chunk) {
|
if (bytes < chunk) {
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
|
@ -51,8 +47,7 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
out += 3;
|
out += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->shuffle((UINT8*) im->image[state->y],
|
state->shuffle((UINT8 *)im->image[state->y], state->buffer, state->xsize);
|
||||||
state->buffer, state->xsize);
|
|
||||||
|
|
||||||
if (++state->y >= state->ysize) {
|
if (++state->y >= state->ysize) {
|
||||||
return -1; /* This can hardly happen */
|
return -1; /* This can hardly happen */
|
||||||
|
@ -67,8 +62,7 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
out += 3;
|
out += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->shuffle((UINT8*) im->image[state->y],
|
state->shuffle((UINT8 *)im->image[state->y], state->buffer, state->xsize);
|
||||||
state->buffer, state->xsize);
|
|
||||||
|
|
||||||
if (++state->y >= state->ysize) {
|
if (++state->y >= state->ysize) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -76,6 +70,5 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
|
|
||||||
ptr += chunk;
|
ptr += chunk;
|
||||||
bytes -= chunk;
|
bytes -= chunk;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,10 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
UINT8 n;
|
UINT8 n;
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
|
|
||||||
|
@ -30,13 +28,11 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (bytes < 1) {
|
if (bytes < 1) {
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*ptr & 0xC0) == 0xC0) {
|
if ((*ptr & 0xC0) == 0xC0) {
|
||||||
|
|
||||||
/* Run */
|
/* Run */
|
||||||
if (bytes < 2) {
|
if (bytes < 2) {
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
|
@ -53,14 +49,14 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += 2; bytes -= 2;
|
ptr += 2;
|
||||||
|
bytes -= 2;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Literal */
|
/* Literal */
|
||||||
state->buffer[state->x++] = ptr[0];
|
state->buffer[state->x++] = ptr[0];
|
||||||
ptr++; bytes--;
|
ptr++;
|
||||||
|
bytes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->x >= state->bytes) {
|
if (state->x >= state->bytes) {
|
||||||
|
@ -69,14 +65,17 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
int stride = state->bytes / bands;
|
int stride = state->bytes / bands;
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; i < bands; i++) { // note -- skipping first band
|
for (i = 1; i < bands; i++) { // note -- skipping first band
|
||||||
memmove(&state->buffer[i*state->xsize],
|
memmove(
|
||||||
|
&state->buffer[i * state->xsize],
|
||||||
&state->buffer[i * stride],
|
&state->buffer[i * stride],
|
||||||
state->xsize);
|
state->xsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Got a full line, unpack it */
|
/* Got a full line, unpack it */
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
state->shuffle(
|
||||||
state->xoff * im->pixelsize, state->buffer,
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
|
state->xoff * im->pixelsize,
|
||||||
|
state->buffer,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
|
||||||
state->x = 0;
|
state->x = 0;
|
||||||
|
@ -86,6 +85,5 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
enum { INIT, FETCH, ENCODE };
|
enum { INIT, FETCH, ENCODE };
|
||||||
|
@ -22,8 +21,7 @@ enum { INIT, FETCH, ENCODE };
|
||||||
#define LAST ystep
|
#define LAST ystep
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
int this;
|
int this;
|
||||||
int bytes_per_line = 0;
|
int bytes_per_line = 0;
|
||||||
|
@ -59,9 +57,7 @@ ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
|
|
||||||
padding = stride - bytes_per_line;
|
padding = stride - bytes_per_line;
|
||||||
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
switch (state->state) {
|
switch (state->state) {
|
||||||
case FETCH:
|
case FETCH:
|
||||||
|
|
||||||
|
@ -71,9 +67,11 @@ ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->shuffle(state->buffer,
|
state->shuffle(
|
||||||
|
state->buffer,
|
||||||
(UINT8 *)im->image[state->y + state->yoff] +
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
state->xoff * im->pixelsize, state->xsize);
|
state->xoff * im->pixelsize,
|
||||||
|
state->xsize);
|
||||||
|
|
||||||
state->y += 1;
|
state->y += 1;
|
||||||
|
|
||||||
|
@ -100,7 +98,6 @@ ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
the double loop
|
the double loop
|
||||||
*/
|
*/
|
||||||
while (state->x % bytes_per_line) {
|
while (state->x % bytes_per_line) {
|
||||||
|
|
||||||
if (state->count == 63) {
|
if (state->count == 63) {
|
||||||
/* this run is full; flush it */
|
/* this run is full; flush it */
|
||||||
if (bytes < 2) {
|
if (bytes < 2) {
|
||||||
|
@ -188,4 +185,3 @@ ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -27,8 +26,7 @@ typedef struct {
|
||||||
} im_point_context;
|
} im_point_context;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
im_point_8_8(Imaging imOut, Imaging imIn, im_point_context* context)
|
im_point_8_8(Imaging imOut, Imaging imIn, im_point_context *context) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
/* 8-bit source, 8-bit destination */
|
/* 8-bit source, 8-bit destination */
|
||||||
UINT8 *table = (UINT8 *)context->table;
|
UINT8 *table = (UINT8 *)context->table;
|
||||||
|
@ -42,8 +40,7 @@ im_point_8_8(Imaging imOut, Imaging imIn, im_point_context* context)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
im_point_2x8_2x8(Imaging imOut, Imaging imIn, im_point_context* context)
|
im_point_2x8_2x8(Imaging imOut, Imaging imIn, im_point_context *context) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
/* 2x8-bit source, 2x8-bit destination */
|
/* 2x8-bit source, 2x8-bit destination */
|
||||||
UINT8 *table = (UINT8 *)context->table;
|
UINT8 *table = (UINT8 *)context->table;
|
||||||
|
@ -53,14 +50,14 @@ im_point_2x8_2x8(Imaging imOut, Imaging imIn, im_point_context* context)
|
||||||
for (x = 0; x < imIn->xsize; x++) {
|
for (x = 0; x < imIn->xsize; x++) {
|
||||||
out[0] = table[in[0]];
|
out[0] = table[in[0]];
|
||||||
out[3] = table[in[3] + 256];
|
out[3] = table[in[3] + 256];
|
||||||
in += 4; out += 4;
|
in += 4;
|
||||||
|
out += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
im_point_3x8_3x8(Imaging imOut, Imaging imIn, im_point_context* context)
|
im_point_3x8_3x8(Imaging imOut, Imaging imIn, im_point_context *context) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
/* 3x8-bit source, 3x8-bit destination */
|
/* 3x8-bit source, 3x8-bit destination */
|
||||||
UINT8 *table = (UINT8 *)context->table;
|
UINT8 *table = (UINT8 *)context->table;
|
||||||
|
@ -71,14 +68,14 @@ im_point_3x8_3x8(Imaging imOut, Imaging imIn, im_point_context* context)
|
||||||
out[0] = table[in[0]];
|
out[0] = table[in[0]];
|
||||||
out[1] = table[in[1] + 256];
|
out[1] = table[in[1] + 256];
|
||||||
out[2] = table[in[2] + 512];
|
out[2] = table[in[2] + 512];
|
||||||
in += 4; out += 4;
|
in += 4;
|
||||||
|
out += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
im_point_4x8_4x8(Imaging imOut, Imaging imIn, im_point_context* context)
|
im_point_4x8_4x8(Imaging imOut, Imaging imIn, im_point_context *context) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
/* 4x8-bit source, 4x8-bit destination */
|
/* 4x8-bit source, 4x8-bit destination */
|
||||||
UINT8 *table = (UINT8 *)context->table;
|
UINT8 *table = (UINT8 *)context->table;
|
||||||
|
@ -90,14 +87,14 @@ im_point_4x8_4x8(Imaging imOut, Imaging imIn, im_point_context* context)
|
||||||
out[1] = table[in[1] + 256];
|
out[1] = table[in[1] + 256];
|
||||||
out[2] = table[in[2] + 512];
|
out[2] = table[in[2] + 512];
|
||||||
out[3] = table[in[3] + 768];
|
out[3] = table[in[3] + 768];
|
||||||
in += 4; out += 4;
|
in += 4;
|
||||||
|
out += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
im_point_8_32(Imaging imOut, Imaging imIn, im_point_context* context)
|
im_point_8_32(Imaging imOut, Imaging imIn, im_point_context *context) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
/* 8-bit source, 32-bit destination */
|
/* 8-bit source, 32-bit destination */
|
||||||
char *table = (char *)context->table;
|
char *table = (char *)context->table;
|
||||||
|
@ -111,8 +108,7 @@ im_point_8_32(Imaging imOut, Imaging imIn, im_point_context* context)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
im_point_32_8(Imaging imOut, Imaging imIn, im_point_context* context)
|
im_point_32_8(Imaging imOut, Imaging imIn, im_point_context *context) {
|
||||||
{
|
|
||||||
int x, y;
|
int x, y;
|
||||||
/* 32-bit source, 8-bit destination */
|
/* 32-bit source, 8-bit destination */
|
||||||
UINT8 *table = (UINT8 *)context->table;
|
UINT8 *table = (UINT8 *)context->table;
|
||||||
|
@ -132,8 +128,7 @@ im_point_32_8(Imaging imOut, Imaging imIn, im_point_context* context)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingPoint(Imaging imIn, const char* mode, const void* table)
|
ImagingPoint(Imaging imIn, const char *mode, const void *table) {
|
||||||
{
|
|
||||||
/* lookup table transform */
|
/* lookup table transform */
|
||||||
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
|
@ -203,22 +198,18 @@ ImagingPoint(Imaging imIn, const char* mode, const void* table)
|
||||||
|
|
||||||
mode_mismatch:
|
mode_mismatch:
|
||||||
return (Imaging)ImagingError_ValueError(
|
return (Imaging)ImagingError_ValueError(
|
||||||
"point operation not supported for this mode"
|
"point operation not supported for this mode");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingPointTransform(Imaging imIn, double scale, double offset)
|
ImagingPointTransform(Imaging imIn, double scale, double offset) {
|
||||||
{
|
|
||||||
/* scale/offset transform */
|
/* scale/offset transform */
|
||||||
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
if (!imIn || (strcmp(imIn->mode, "I") != 0 &&
|
if (!imIn || (strcmp(imIn->mode, "I") != 0 && strcmp(imIn->mode, "I;16") != 0 &&
|
||||||
strcmp(imIn->mode, "I;16") != 0 &&
|
|
||||||
strcmp(imIn->mode, "F") != 0)) {
|
strcmp(imIn->mode, "F") != 0)) {
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,29 +66,24 @@ typedef struct _BoxNode {
|
||||||
#define MAX_HASH_ENTRIES 65536
|
#define MAX_HASH_ENTRIES 65536
|
||||||
|
|
||||||
#define PIXEL_HASH(r, g, b) \
|
#define PIXEL_HASH(r, g, b) \
|
||||||
(((unsigned int)(r) )*463 ^ \
|
(((unsigned int)(r)) * 463 ^ ((unsigned int)(g) << 8) * 10069 ^ \
|
||||||
((unsigned int)(g)<< 8)*10069 ^ \
|
|
||||||
((unsigned int)(b) << 16) * 64997)
|
((unsigned int)(b) << 16) * 64997)
|
||||||
|
|
||||||
#define PIXEL_UNSCALE(p, q, s) \
|
#define PIXEL_UNSCALE(p, q, s) \
|
||||||
((q)->c.r=(p)->c.r<<(s)), \
|
((q)->c.r = (p)->c.r << (s)), ((q)->c.g = (p)->c.g << (s)), \
|
||||||
((q)->c.g=(p)->c.g<<(s)), \
|
|
||||||
((q)->c.b = (p)->c.b << (s))
|
((q)->c.b = (p)->c.b << (s))
|
||||||
|
|
||||||
#define PIXEL_SCALE(p, q, s) \
|
#define PIXEL_SCALE(p, q, s) \
|
||||||
((q)->c.r=(p)->c.r>>(s)), \
|
((q)->c.r = (p)->c.r >> (s)), ((q)->c.g = (p)->c.g >> (s)), \
|
||||||
((q)->c.g=(p)->c.g>>(s)), \
|
|
||||||
((q)->c.b = (p)->c.b >> (s))
|
((q)->c.b = (p)->c.b >> (s))
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
unshifted_pixel_hash(const HashTable *h, const Pixel pixel)
|
unshifted_pixel_hash(const HashTable *h, const Pixel pixel) {
|
||||||
{
|
|
||||||
return PIXEL_HASH(pixel.c.r, pixel.c.g, pixel.c.b);
|
return PIXEL_HASH(pixel.c.r, pixel.c.g, pixel.c.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
unshifted_pixel_cmp(const HashTable *h, const Pixel pixel1, const Pixel pixel2)
|
unshifted_pixel_cmp(const HashTable *h, const Pixel pixel1, const Pixel pixel2) {
|
||||||
{
|
|
||||||
if (pixel1.c.r == pixel2.c.r) {
|
if (pixel1.c.r == pixel2.c.r) {
|
||||||
if (pixel1.c.g == pixel2.c.g) {
|
if (pixel1.c.g == pixel2.c.g) {
|
||||||
if (pixel1.c.b == pixel2.c.b) {
|
if (pixel1.c.b == pixel2.c.b) {
|
||||||
|
@ -105,49 +100,43 @@ unshifted_pixel_cmp(const HashTable *h, const Pixel pixel1, const Pixel pixel2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
pixel_hash(const HashTable *h,const Pixel pixel)
|
pixel_hash(const HashTable *h, const Pixel pixel) {
|
||||||
{
|
|
||||||
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
|
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
|
||||||
return PIXEL_HASH(pixel.c.r>>d->scale, pixel.c.g>>d->scale, pixel.c.b>>d->scale);
|
return PIXEL_HASH(
|
||||||
|
pixel.c.r >> d->scale, pixel.c.g >> d->scale, pixel.c.b >> d->scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pixel_cmp(const HashTable *h,const Pixel pixel1, const Pixel pixel2)
|
pixel_cmp(const HashTable *h, const Pixel pixel1, const Pixel pixel2) {
|
||||||
{
|
|
||||||
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
|
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
|
||||||
uint32_t A, B;
|
uint32_t A, B;
|
||||||
A=PIXEL_HASH(pixel1.c.r>>d->scale, pixel1.c.g>>d->scale, pixel1.c.b>>d->scale);
|
A = PIXEL_HASH(
|
||||||
B=PIXEL_HASH(pixel2.c.r>>d->scale, pixel2.c.g>>d->scale, pixel2.c.b>>d->scale);
|
pixel1.c.r >> d->scale, pixel1.c.g >> d->scale, pixel1.c.b >> d->scale);
|
||||||
|
B = PIXEL_HASH(
|
||||||
|
pixel2.c.r >> d->scale, pixel2.c.g >> d->scale, pixel2.c.b >> d->scale);
|
||||||
return (A == B) ? 0 : ((A < B) ? -1 : 1);
|
return (A == B) ? 0 : ((A < B) ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
exists_count_func(const HashTable *h, const Pixel key, uint32_t *val)
|
exists_count_func(const HashTable *h, const Pixel key, uint32_t *val) {
|
||||||
{
|
|
||||||
*val += 1;
|
*val += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
new_count_func(const HashTable *h, const Pixel key, uint32_t *val)
|
new_count_func(const HashTable *h, const Pixel key, uint32_t *val) {
|
||||||
{
|
|
||||||
*val = 1;
|
*val = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rehash_collide(const HashTable *h,
|
rehash_collide(
|
||||||
Pixel *keyp,
|
const HashTable *h, Pixel *keyp, uint32_t *valp, Pixel newkey, uint32_t newval) {
|
||||||
uint32_t *valp,
|
|
||||||
Pixel newkey,
|
|
||||||
uint32_t newval)
|
|
||||||
{
|
|
||||||
*valp += newval;
|
*valp += newval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* %% */
|
/* %% */
|
||||||
|
|
||||||
static HashTable *
|
static HashTable *
|
||||||
create_pixel_hash(Pixel *pixelData,uint32_t nPixels)
|
create_pixel_hash(Pixel *pixelData, uint32_t nPixels) {
|
||||||
{
|
|
||||||
PixelHashData *d;
|
PixelHashData *d;
|
||||||
HashTable *hash;
|
HashTable *hash;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -167,10 +156,9 @@ create_pixel_hash(Pixel *pixelData,uint32_t nPixels)
|
||||||
timer = timer3 = clock();
|
timer = timer3 = clock();
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < nPixels; i++) {
|
for (i = 0; i < nPixels; i++) {
|
||||||
if (!hashtable_insert_or_update_computed(hash,
|
if (!hashtable_insert_or_update_computed(
|
||||||
pixelData[i],
|
hash, pixelData[i], new_count_func, exists_count_func)) {
|
||||||
new_count_func,
|
;
|
||||||
exists_count_func)) {;
|
|
||||||
}
|
}
|
||||||
while (hashtable_get_count(hash) > MAX_HASH_ENTRIES) {
|
while (hashtable_get_count(hash) > MAX_HASH_ENTRIES) {
|
||||||
d->scale++;
|
d->scale++;
|
||||||
|
@ -196,8 +184,7 @@ create_pixel_hash(Pixel *pixelData,uint32_t nPixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_pixel_hash(HashTable *hash)
|
destroy_pixel_hash(HashTable *hash) {
|
||||||
{
|
|
||||||
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(hash);
|
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(hash);
|
||||||
if (d) {
|
if (d) {
|
||||||
free(d);
|
free(d);
|
||||||
|
@ -205,7 +192,6 @@ destroy_pixel_hash(HashTable *hash)
|
||||||
hashtable_free(hash);
|
hashtable_free(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 1. hash quantized pixels. */
|
/* 1. hash quantized pixels. */
|
||||||
/* 2. create R,G,B lists of sorted quantized pixels. */
|
/* 2. create R,G,B lists of sorted quantized pixels. */
|
||||||
/* 3. median cut. */
|
/* 3. median cut. */
|
||||||
|
@ -215,8 +201,7 @@ destroy_pixel_hash(HashTable *hash)
|
||||||
/* 7. map each pixel to nearest average. */
|
/* 7. map each pixel to nearest average. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compute_box_volume(BoxNode *b)
|
compute_box_volume(BoxNode *b) {
|
||||||
{
|
|
||||||
unsigned char rl, rh, gl, gh, bl, bh;
|
unsigned char rl, rh, gl, gh, bl, bh;
|
||||||
if (b->volume >= 0) {
|
if (b->volume >= 0) {
|
||||||
return b->volume;
|
return b->volume;
|
||||||
|
@ -236,8 +221,7 @@ compute_box_volume(BoxNode *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void *u)
|
hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void *u) {
|
||||||
{
|
|
||||||
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
|
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
|
||||||
PixelList **pl = (PixelList **)u;
|
PixelList **pl = (PixelList **)u;
|
||||||
PixelList *p;
|
PixelList *p;
|
||||||
|
@ -266,8 +250,7 @@ hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void *
|
||||||
}
|
}
|
||||||
|
|
||||||
static PixelList *
|
static PixelList *
|
||||||
mergesort_pixels(PixelList *head, int i)
|
mergesort_pixels(PixelList *head, int i) {
|
||||||
{
|
|
||||||
PixelList *c, *t, *a, *b, *p;
|
PixelList *c, *t, *a, *b, *p;
|
||||||
if (!head || !head->next[i]) {
|
if (!head || !head->next[i]) {
|
||||||
if (head) {
|
if (head) {
|
||||||
|
@ -276,7 +259,9 @@ mergesort_pixels(PixelList *head, int i)
|
||||||
}
|
}
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
for (c=t=head;c&&t;c=c->next[i],t=(t->next[i])?t->next[i]->next[i]:NULL);
|
for (c = t = head; c && t;
|
||||||
|
c = c->next[i], t = (t->next[i]) ? t->next[i]->next[i] : NULL)
|
||||||
|
;
|
||||||
if (c) {
|
if (c) {
|
||||||
if (c->prev[i]) {
|
if (c->prev[i]) {
|
||||||
c->prev[i]->next[i] = NULL;
|
c->prev[i]->next[i] = NULL;
|
||||||
|
@ -317,8 +302,7 @@ mergesort_pixels(PixelList *head, int i)
|
||||||
|
|
||||||
#if defined(TEST_MERGESORT) || defined(TEST_SORTED)
|
#if defined(TEST_MERGESORT) || defined(TEST_SORTED)
|
||||||
static int
|
static int
|
||||||
test_sorted(PixelList *pl[3])
|
test_sorted(PixelList *pl[3]) {
|
||||||
{
|
|
||||||
int i, n, l;
|
int i, n, l;
|
||||||
PixelList *t;
|
PixelList *t;
|
||||||
|
|
||||||
|
@ -326,7 +310,8 @@ test_sorted(PixelList *pl[3])
|
||||||
n = 0;
|
n = 0;
|
||||||
l = 256;
|
l = 256;
|
||||||
for (t = pl[i]; t; t = t->next[i]) {
|
for (t = pl[i]; t; t = t->next[i]) {
|
||||||
if (l<t->p.a.v[i]) return 0;
|
if (l < t->p.a.v[i])
|
||||||
|
return 0;
|
||||||
l = t->p.a.v[i];
|
l = t->p.a.v[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,8 +320,7 @@ test_sorted(PixelList *pl[3])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
box_heap_cmp(const Heap *h, const void *A, const void *B)
|
box_heap_cmp(const Heap *h, const void *A, const void *B) {
|
||||||
{
|
|
||||||
BoxNode *a = (BoxNode *)A;
|
BoxNode *a = (BoxNode *)A;
|
||||||
BoxNode *b = (BoxNode *)B;
|
BoxNode *b = (BoxNode *)B;
|
||||||
return (int)a->pixelCount - (int)b->pixelCount;
|
return (int)a->pixelCount - (int)b->pixelCount;
|
||||||
|
@ -345,14 +329,14 @@ box_heap_cmp(const Heap *h, const void *A, const void *B)
|
||||||
#define LUMINANCE(p) (77 * (p)->c.r + 150 * (p)->c.g + 29 * (p)->c.b)
|
#define LUMINANCE(p) (77 * (p)->c.r + 150 * (p)->c.g + 29 * (p)->c.b)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
splitlists(PixelList *h[3],
|
splitlists(
|
||||||
|
PixelList *h[3],
|
||||||
PixelList *t[3],
|
PixelList *t[3],
|
||||||
PixelList *nh[2][3],
|
PixelList *nh[2][3],
|
||||||
PixelList *nt[2][3],
|
PixelList *nt[2][3],
|
||||||
uint32_t nCount[2],
|
uint32_t nCount[2],
|
||||||
int axis,
|
int axis,
|
||||||
uint32_t pixelCount)
|
uint32_t pixelCount) {
|
||||||
{
|
|
||||||
uint32_t left;
|
uint32_t left;
|
||||||
|
|
||||||
PixelList *l, *r, *c, *n;
|
PixelList *l, *r, *c, *n;
|
||||||
|
@ -365,8 +349,14 @@ splitlists(PixelList *h[3],
|
||||||
PixelList *_prevTest, *_nextTest;
|
PixelList *_prevTest, *_nextTest;
|
||||||
int _i, _nextCount[3], _prevCount[3];
|
int _i, _nextCount[3], _prevCount[3];
|
||||||
for (_i = 0; _i < 3; _i++) {
|
for (_i = 0; _i < 3; _i++) {
|
||||||
for (_nextCount[_i]=0,_nextTest=h[_i];_nextTest&&_nextTest->next[_i];_nextTest=_nextTest->next[_i],_nextCount[_i]++);
|
for (_nextCount[_i] = 0, _nextTest = h[_i];
|
||||||
for (_prevCount[_i]=0,_prevTest=t[_i];_prevTest&&_prevTest->prev[_i];_prevTest=_prevTest->prev[_i],_prevCount[_i]++);
|
_nextTest && _nextTest->next[_i];
|
||||||
|
_nextTest = _nextTest->next[_i], _nextCount[_i]++)
|
||||||
|
;
|
||||||
|
for (_prevCount[_i] = 0, _prevTest = t[_i];
|
||||||
|
_prevTest && _prevTest->prev[_i];
|
||||||
|
_prevTest = _prevTest->prev[_i], _prevCount[_i]++)
|
||||||
|
;
|
||||||
if (_nextTest != t[_i]) {
|
if (_nextTest != t[_i]) {
|
||||||
printf("next-list of axis %d does not end at tail\n", _i);
|
printf("next-list of axis %d does not end at tail\n", _i);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -375,8 +365,10 @@ splitlists(PixelList *h[3],
|
||||||
printf("prev-list of axis %d does not end at head\n", _i);
|
printf("prev-list of axis %d does not end at head\n", _i);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
for (;_nextTest&&_nextTest->prev[_i];_nextTest=_nextTest->prev[_i]);
|
for (; _nextTest && _nextTest->prev[_i]; _nextTest = _nextTest->prev[_i])
|
||||||
for (;_prevTest&&_prevTest->next[_i];_prevTest=_prevTest->next[_i]);
|
;
|
||||||
|
for (; _prevTest && _prevTest->next[_i]; _prevTest = _prevTest->next[_i])
|
||||||
|
;
|
||||||
if (_nextTest != h[_i]) {
|
if (_nextTest != h[_i]) {
|
||||||
printf("next-list of axis %d does not loop back to head\n", _i);
|
printf("next-list of axis %d does not loop back to head\n", _i);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -390,7 +382,8 @@ splitlists(PixelList *h[3],
|
||||||
if (_prevCount[_i] != _prevCount[_i - 1] ||
|
if (_prevCount[_i] != _prevCount[_i - 1] ||
|
||||||
_nextCount[_i] != _nextCount[_i - 1] ||
|
_nextCount[_i] != _nextCount[_i - 1] ||
|
||||||
_prevCount[_i] != _nextCount[_i]) {
|
_prevCount[_i] != _nextCount[_i]) {
|
||||||
printf ("{%d %d %d} {%d %d %d}\n",
|
printf(
|
||||||
|
"{%d %d %d} {%d %d %d}\n",
|
||||||
_prevCount[0],
|
_prevCount[0],
|
||||||
_prevCount[1],
|
_prevCount[1],
|
||||||
_prevCount[2],
|
_prevCount[2],
|
||||||
|
@ -488,8 +481,7 @@ splitlists(PixelList *h[3],
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
split(BoxNode *node)
|
split(BoxNode *node) {
|
||||||
{
|
|
||||||
unsigned char rl, rh, gl, gh, bl, bh;
|
unsigned char rl, rh, gl, gh, bl, bh;
|
||||||
int f[3];
|
int f[3];
|
||||||
int best, axis;
|
int best, axis;
|
||||||
|
@ -515,7 +507,10 @@ split(BoxNode *node)
|
||||||
best = f[0];
|
best = f[0];
|
||||||
axis = 0;
|
axis = 0;
|
||||||
for (i = 1; i < 3; i++) {
|
for (i = 1; i < 3; i++) {
|
||||||
if (best<f[i]) { best=f[i]; axis=i; }
|
if (best < f[i]) {
|
||||||
|
best = f[i];
|
||||||
|
axis = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef TEST_SPLIT
|
#ifdef TEST_SPLIT
|
||||||
printf("along axis %d\n", axis + 1);
|
printf("along axis %d\n", axis + 1);
|
||||||
|
@ -528,25 +523,35 @@ split(BoxNode *node)
|
||||||
for (_i = 0; _i < 3; _i++) {
|
for (_i = 0; _i < 3; _i++) {
|
||||||
if (node->tail[_i]->next[_i]) {
|
if (node->tail[_i]->next[_i]) {
|
||||||
printf("tail is not tail\n");
|
printf("tail is not tail\n");
|
||||||
printf ("node->tail[%d]->next[%d]=%p\n",_i,_i,node->tail[_i]->next[_i]);
|
printf(
|
||||||
|
"node->tail[%d]->next[%d]=%p\n", _i, _i, node->tail[_i]->next[_i]);
|
||||||
}
|
}
|
||||||
if (node->head[_i]->prev[_i]) {
|
if (node->head[_i]->prev[_i]) {
|
||||||
printf("head is not head\n");
|
printf("head is not head\n");
|
||||||
printf ("node->head[%d]->prev[%d]=%p\n",_i,_i,node->head[_i]->prev[_i]);
|
printf(
|
||||||
|
"node->head[%d]->prev[%d]=%p\n", _i, _i, node->head[_i]->prev[_i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_i = 0; _i < 3; _i++) {
|
for (_i = 0; _i < 3; _i++) {
|
||||||
for (_nextCount[_i]=0,_nextTest=node->head[_i];_nextTest&&_nextTest->next[_i];_nextTest=_nextTest->next[_i],_nextCount[_i]++);
|
for (_nextCount[_i] = 0, _nextTest = node->head[_i];
|
||||||
for (_prevCount[_i]=0,_prevTest=node->tail[_i];_prevTest&&_prevTest->prev[_i];_prevTest=_prevTest->prev[_i],_prevCount[_i]++);
|
_nextTest && _nextTest->next[_i];
|
||||||
|
_nextTest = _nextTest->next[_i], _nextCount[_i]++)
|
||||||
|
;
|
||||||
|
for (_prevCount[_i] = 0, _prevTest = node->tail[_i];
|
||||||
|
_prevTest && _prevTest->prev[_i];
|
||||||
|
_prevTest = _prevTest->prev[_i], _prevCount[_i]++)
|
||||||
|
;
|
||||||
if (_nextTest != node->tail[_i]) {
|
if (_nextTest != node->tail[_i]) {
|
||||||
printf("next-list of axis %d does not end at tail\n", _i);
|
printf("next-list of axis %d does not end at tail\n", _i);
|
||||||
}
|
}
|
||||||
if (_prevTest != node->head[_i]) {
|
if (_prevTest != node->head[_i]) {
|
||||||
printf("prev-list of axis %d does not end at head\n", _i);
|
printf("prev-list of axis %d does not end at head\n", _i);
|
||||||
}
|
}
|
||||||
for (;_nextTest&&_nextTest->prev[_i];_nextTest=_nextTest->prev[_i]);
|
for (; _nextTest && _nextTest->prev[_i]; _nextTest = _nextTest->prev[_i])
|
||||||
for (;_prevTest&&_prevTest->next[_i];_prevTest=_prevTest->next[_i]);
|
;
|
||||||
|
for (; _prevTest && _prevTest->next[_i]; _prevTest = _prevTest->next[_i])
|
||||||
|
;
|
||||||
if (_nextTest != node->head[_i]) {
|
if (_nextTest != node->head[_i]) {
|
||||||
printf("next-list of axis %d does not loop back to head\n", _i);
|
printf("next-list of axis %d does not loop back to head\n", _i);
|
||||||
}
|
}
|
||||||
|
@ -558,7 +563,8 @@ split(BoxNode *node)
|
||||||
if (_prevCount[_i] != _prevCount[_i - 1] ||
|
if (_prevCount[_i] != _prevCount[_i - 1] ||
|
||||||
_nextCount[_i] != _nextCount[_i - 1] ||
|
_nextCount[_i] != _nextCount[_i - 1] ||
|
||||||
_prevCount[_i] != _nextCount[_i]) {
|
_prevCount[_i] != _nextCount[_i]) {
|
||||||
printf ("{%d %d %d} {%d %d %d}\n",
|
printf(
|
||||||
|
"{%d %d %d} {%d %d %d}\n",
|
||||||
_prevCount[0],
|
_prevCount[0],
|
||||||
_prevCount[1],
|
_prevCount[1],
|
||||||
_prevCount[2],
|
_prevCount[2],
|
||||||
|
@ -570,13 +576,8 @@ split(BoxNode *node)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
node->axis = axis;
|
node->axis = axis;
|
||||||
if (!splitlists(node->head,
|
if (!splitlists(
|
||||||
node->tail,
|
node->head, node->tail, heads, tails, newCounts, axis, node->pixelCount)) {
|
||||||
heads,
|
|
||||||
tails,
|
|
||||||
newCounts,
|
|
||||||
axis,
|
|
||||||
node->pixelCount)) {
|
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf("list split failed.\n");
|
printf("list split failed.\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -640,10 +641,7 @@ split(BoxNode *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
static BoxNode *
|
static BoxNode *
|
||||||
median_cut(PixelList *hl[3],
|
median_cut(PixelList *hl[3], uint32_t imPixelCount, int nPixels) {
|
||||||
uint32_t imPixelCount,
|
|
||||||
int nPixels)
|
|
||||||
{
|
|
||||||
PixelList *tl[3];
|
PixelList *tl[3];
|
||||||
int i;
|
int i;
|
||||||
BoxNode *root;
|
BoxNode *root;
|
||||||
|
@ -653,9 +651,13 @@ median_cut(PixelList *hl[3],
|
||||||
h = ImagingQuantHeapNew(box_heap_cmp);
|
h = ImagingQuantHeapNew(box_heap_cmp);
|
||||||
/* malloc check ok, small constant allocation */
|
/* malloc check ok, small constant allocation */
|
||||||
root = malloc(sizeof(BoxNode));
|
root = malloc(sizeof(BoxNode));
|
||||||
if (!root) { ImagingQuantHeapFree(h); return NULL; }
|
if (!root) {
|
||||||
|
ImagingQuantHeapFree(h);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
for (tl[i]=hl[i];tl[i]&&tl[i]->next[i];tl[i]=tl[i]->next[i]);
|
for (tl[i] = hl[i]; tl[i] && tl[i]->next[i]; tl[i] = tl[i]->next[i])
|
||||||
|
;
|
||||||
root->head[i] = hl[i];
|
root->head[i] = hl[i];
|
||||||
root->tail[i] = tl[i];
|
root->tail[i] = tl[i];
|
||||||
}
|
}
|
||||||
|
@ -686,8 +688,7 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_box_tree(BoxNode *n)
|
free_box_tree(BoxNode *n) {
|
||||||
{
|
|
||||||
PixelList *p, *pp;
|
PixelList *p, *pp;
|
||||||
if (n->l) {
|
if (n->l) {
|
||||||
free_box_tree(n->l);
|
free_box_tree(n->l);
|
||||||
|
@ -704,8 +705,7 @@ free_box_tree(BoxNode *n)
|
||||||
|
|
||||||
#ifdef TEST_SPLIT_INTEGRITY
|
#ifdef TEST_SPLIT_INTEGRITY
|
||||||
static int
|
static int
|
||||||
checkContained(BoxNode *n,Pixel *pp)
|
checkContained(BoxNode *n, Pixel *pp) {
|
||||||
{
|
|
||||||
if (n->l && n->r) {
|
if (n->l && n->r) {
|
||||||
return checkContained(n->l, pp) + checkContained(n->r, pp);
|
return checkContained(n->l, pp) + checkContained(n->r, pp);
|
||||||
}
|
}
|
||||||
|
@ -715,13 +715,9 @@ checkContained(BoxNode *n,Pixel *pp)
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (
|
if (pp->c.r <= n->head[0]->p.c.r && pp->c.r >= n->tail[0]->p.c.r &&
|
||||||
pp->c.r<=n->head[0]->p.c.r &&
|
pp->c.g <= n->head[1]->p.c.g && pp->c.g >= n->tail[1]->p.c.g &&
|
||||||
pp->c.r>=n->tail[0]->p.c.r &&
|
pp->c.b <= n->head[2]->p.c.b && pp->c.b >= n->tail[2]->p.c.b) {
|
||||||
pp->c.g<=n->head[1]->p.c.g &&
|
|
||||||
pp->c.g>=n->tail[1]->p.c.g &&
|
|
||||||
pp->c.b<=n->head[2]->p.c.b &&
|
|
||||||
pp->c.b>=n->tail[2]->p.c.b) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -729,8 +725,7 @@ checkContained(BoxNode *n,Pixel *pp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
annotate_hash_table(BoxNode *n,HashTable *h,uint32_t *box)
|
annotate_hash_table(BoxNode *n, HashTable *h, uint32_t *box) {
|
||||||
{
|
|
||||||
PixelList *p;
|
PixelList *p;
|
||||||
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
|
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
|
||||||
Pixel q;
|
Pixel q;
|
||||||
|
@ -759,19 +754,15 @@ annotate_hash_table(BoxNode *n,HashTable *h,uint32_t *box)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_sort_ulong_ptr_keys(const void *a, const void *b)
|
_sort_ulong_ptr_keys(const void *a, const void *b) {
|
||||||
{
|
|
||||||
uint32_t A = **(uint32_t **)a;
|
uint32_t A = **(uint32_t **)a;
|
||||||
uint32_t B = **(uint32_t **)b;
|
uint32_t B = **(uint32_t **)b;
|
||||||
return (A == B) ? 0 : ((A < B) ? -1 : +1);
|
return (A == B) ? 0 : ((A < B) ? -1 : +1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
resort_distance_tables(uint32_t *avgDist,
|
resort_distance_tables(
|
||||||
uint32_t **avgDistSortKey,
|
uint32_t *avgDist, uint32_t **avgDistSortKey, Pixel *p, uint32_t nEntries) {
|
||||||
Pixel *p,
|
|
||||||
uint32_t nEntries)
|
|
||||||
{
|
|
||||||
uint32_t i, j, k;
|
uint32_t i, j, k;
|
||||||
uint32_t **skRow;
|
uint32_t **skRow;
|
||||||
uint32_t *skElt;
|
uint32_t *skElt;
|
||||||
|
@ -779,8 +770,8 @@ resort_distance_tables(uint32_t *avgDist,
|
||||||
for (i = 0; i < nEntries; i++) {
|
for (i = 0; i < nEntries; i++) {
|
||||||
avgDist[i * nEntries + i] = 0;
|
avgDist[i * nEntries + i] = 0;
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
avgDist[j*nEntries+i]=
|
avgDist[j * nEntries + i] = avgDist[i * nEntries + j] =
|
||||||
avgDist[i*nEntries+j]=_DISTSQR(p+i,p+j);
|
_DISTSQR(p + i, p + j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < nEntries; i++) {
|
for (i = 0; i < nEntries; i++) {
|
||||||
|
@ -799,25 +790,23 @@ resort_distance_tables(uint32_t *avgDist,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
build_distance_tables(uint32_t *avgDist,
|
build_distance_tables(
|
||||||
uint32_t **avgDistSortKey,
|
uint32_t *avgDist, uint32_t **avgDistSortKey, Pixel *p, uint32_t nEntries) {
|
||||||
Pixel *p,
|
|
||||||
uint32_t nEntries)
|
|
||||||
{
|
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
|
|
||||||
for (i = 0; i < nEntries; i++) {
|
for (i = 0; i < nEntries; i++) {
|
||||||
avgDist[i * nEntries + i] = 0;
|
avgDist[i * nEntries + i] = 0;
|
||||||
avgDistSortKey[i * nEntries + i] = &(avgDist[i * nEntries + i]);
|
avgDistSortKey[i * nEntries + i] = &(avgDist[i * nEntries + i]);
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
avgDist[j*nEntries+i]=
|
avgDist[j * nEntries + i] = avgDist[i * nEntries + j] =
|
||||||
avgDist[i*nEntries+j]=_DISTSQR(p+i,p+j);
|
_DISTSQR(p + i, p + j);
|
||||||
avgDistSortKey[j * nEntries + i] = &(avgDist[j * nEntries + i]);
|
avgDistSortKey[j * nEntries + i] = &(avgDist[j * nEntries + i]);
|
||||||
avgDistSortKey[i * nEntries + j] = &(avgDist[i * nEntries + j]);
|
avgDistSortKey[i * nEntries + j] = &(avgDist[i * nEntries + j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < nEntries; i++) {
|
for (i = 0; i < nEntries; i++) {
|
||||||
qsort(avgDistSortKey+i*nEntries,
|
qsort(
|
||||||
|
avgDistSortKey + i * nEntries,
|
||||||
nEntries,
|
nEntries,
|
||||||
sizeof(uint32_t *),
|
sizeof(uint32_t *),
|
||||||
_sort_ulong_ptr_keys);
|
_sort_ulong_ptr_keys);
|
||||||
|
@ -826,14 +815,14 @@ build_distance_tables(uint32_t *avgDist,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
map_image_pixels(Pixel *pixelData,
|
map_image_pixels(
|
||||||
|
Pixel *pixelData,
|
||||||
uint32_t nPixels,
|
uint32_t nPixels,
|
||||||
Pixel *paletteData,
|
Pixel *paletteData,
|
||||||
uint32_t nPaletteEntries,
|
uint32_t nPaletteEntries,
|
||||||
uint32_t *avgDist,
|
uint32_t *avgDist,
|
||||||
uint32_t **avgDistSortKey,
|
uint32_t **avgDistSortKey,
|
||||||
uint32_t *pixelArray)
|
uint32_t *pixelArray) {
|
||||||
{
|
|
||||||
uint32_t *aD, **aDSK;
|
uint32_t *aD, **aDSK;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
|
@ -880,8 +869,7 @@ map_image_pixels_from_quantized_pixels(
|
||||||
uint32_t **avgDistSortKey,
|
uint32_t **avgDistSortKey,
|
||||||
uint32_t *pixelArray,
|
uint32_t *pixelArray,
|
||||||
uint32_t *avg[3],
|
uint32_t *avg[3],
|
||||||
uint32_t *count)
|
uint32_t *count) {
|
||||||
{
|
|
||||||
uint32_t *aD, **aDSK;
|
uint32_t *aD, **aDSK;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
|
@ -939,8 +927,7 @@ map_image_pixels_from_median_box(
|
||||||
HashTable *medianBoxHash,
|
HashTable *medianBoxHash,
|
||||||
uint32_t *avgDist,
|
uint32_t *avgDist,
|
||||||
uint32_t **avgDistSortKey,
|
uint32_t **avgDistSortKey,
|
||||||
uint32_t *pixelArray)
|
uint32_t *pixelArray) {
|
||||||
{
|
|
||||||
uint32_t *aD, **aDSK;
|
uint32_t *aD, **aDSK;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
|
@ -992,8 +979,7 @@ compute_palette_from_median_cut(
|
||||||
uint32_t nPixels,
|
uint32_t nPixels,
|
||||||
HashTable *medianBoxHash,
|
HashTable *medianBoxHash,
|
||||||
Pixel **palette,
|
Pixel **palette,
|
||||||
uint32_t nPaletteEntries)
|
uint32_t nPaletteEntries) {
|
||||||
{
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint32_t paletteEntry;
|
uint32_t paletteEntry;
|
||||||
Pixel *p;
|
Pixel *p;
|
||||||
|
@ -1022,7 +1008,10 @@ compute_palette_from_median_cut(
|
||||||
}
|
}
|
||||||
for (i = 0; i < nPixels; i++) {
|
for (i = 0; i < nPixels; i++) {
|
||||||
#ifdef TEST_SPLIT_INTEGRITY
|
#ifdef TEST_SPLIT_INTEGRITY
|
||||||
if (!(i%100)) { printf ("%05d\r",i); fflush(stdout); }
|
if (!(i % 100)) {
|
||||||
|
printf("%05d\r", i);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
if (checkContained(root, pixelData + i) > 1) {
|
if (checkContained(root, pixelData + i) > 1) {
|
||||||
printf("pixel in two boxes\n");
|
printf("pixel in two boxes\n");
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
|
@ -1044,7 +1033,10 @@ compute_palette_from_median_cut(
|
||||||
}
|
}
|
||||||
if (paletteEntry >= nPaletteEntries) {
|
if (paletteEntry >= nPaletteEntries) {
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf ("panic - paletteEntry>=nPaletteEntries (%d>=%d)\n",(int)paletteEntry,(int)nPaletteEntries);
|
printf(
|
||||||
|
"panic - paletteEntry>=nPaletteEntries (%d>=%d)\n",
|
||||||
|
(int)paletteEntry,
|
||||||
|
(int)nPaletteEntries);
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
free(avg[i]);
|
free(avg[i]);
|
||||||
|
@ -1081,11 +1073,7 @@ compute_palette_from_median_cut(
|
||||||
|
|
||||||
static int
|
static int
|
||||||
recompute_palette_from_averages(
|
recompute_palette_from_averages(
|
||||||
Pixel *palette,
|
Pixel *palette, uint32_t nPaletteEntries, uint32_t *avg[3], uint32_t *count) {
|
||||||
uint32_t nPaletteEntries,
|
|
||||||
uint32_t *avg[3],
|
|
||||||
uint32_t *count)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < nPaletteEntries; i++) {
|
for (i = 0; i < nPaletteEntries; i++) {
|
||||||
|
@ -1104,8 +1092,7 @@ compute_palette_from_quantized_pixels(
|
||||||
uint32_t nPaletteEntries,
|
uint32_t nPaletteEntries,
|
||||||
uint32_t *avg[3],
|
uint32_t *avg[3],
|
||||||
uint32_t *count,
|
uint32_t *count,
|
||||||
uint32_t *qp)
|
uint32_t *qp) {
|
||||||
{
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
memset(count, 0, sizeof(uint32_t) * nPaletteEntries);
|
memset(count, 0, sizeof(uint32_t) * nPaletteEntries);
|
||||||
|
@ -1133,13 +1120,13 @@ compute_palette_from_quantized_pixels(
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
k_means(Pixel *pixelData,
|
k_means(
|
||||||
|
Pixel *pixelData,
|
||||||
uint32_t nPixels,
|
uint32_t nPixels,
|
||||||
Pixel *paletteData,
|
Pixel *paletteData,
|
||||||
uint32_t nPaletteEntries,
|
uint32_t nPaletteEntries,
|
||||||
uint32_t *qp,
|
uint32_t *qp,
|
||||||
int threshold)
|
int threshold) {
|
||||||
{
|
|
||||||
uint32_t *avg[3];
|
uint32_t *avg[3];
|
||||||
uint32_t *count;
|
uint32_t *count;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -1171,25 +1158,34 @@ k_means(Pixel *pixelData,
|
||||||
}
|
}
|
||||||
/* malloc check ok, using calloc, checking n*n above */
|
/* malloc check ok, using calloc, checking n*n above */
|
||||||
avgDist = calloc(nPaletteEntries * nPaletteEntries, sizeof(uint32_t));
|
avgDist = calloc(nPaletteEntries * nPaletteEntries, sizeof(uint32_t));
|
||||||
if (!avgDist) { goto error_1; }
|
if (!avgDist) {
|
||||||
|
goto error_1;
|
||||||
|
}
|
||||||
|
|
||||||
/* malloc check ok, using calloc, checking n*n above */
|
/* malloc check ok, using calloc, checking n*n above */
|
||||||
avgDistSortKey = calloc(nPaletteEntries * nPaletteEntries, sizeof(uint32_t *));
|
avgDistSortKey = calloc(nPaletteEntries * nPaletteEntries, sizeof(uint32_t *));
|
||||||
if (!avgDistSortKey) { goto error_2; }
|
if (!avgDistSortKey) {
|
||||||
|
goto error_2;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf("[");fflush(stdout);
|
printf("[");
|
||||||
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!built) {
|
if (!built) {
|
||||||
compute_palette_from_quantized_pixels(pixelData,nPixels,paletteData,nPaletteEntries,avg,count,qp);
|
compute_palette_from_quantized_pixels(
|
||||||
build_distance_tables(avgDist,avgDistSortKey,paletteData,nPaletteEntries);
|
pixelData, nPixels, paletteData, nPaletteEntries, avg, count, qp);
|
||||||
|
build_distance_tables(
|
||||||
|
avgDist, avgDistSortKey, paletteData, nPaletteEntries);
|
||||||
built = 1;
|
built = 1;
|
||||||
} else {
|
} else {
|
||||||
recompute_palette_from_averages(paletteData, nPaletteEntries, avg, count);
|
recompute_palette_from_averages(paletteData, nPaletteEntries, avg, count);
|
||||||
resort_distance_tables(avgDist,avgDistSortKey,paletteData,nPaletteEntries);
|
resort_distance_tables(
|
||||||
|
avgDist, avgDistSortKey, paletteData, nPaletteEntries);
|
||||||
}
|
}
|
||||||
changes=map_image_pixels_from_quantized_pixels(pixelData,
|
changes = map_image_pixels_from_quantized_pixels(
|
||||||
|
pixelData,
|
||||||
nPixels,
|
nPixels,
|
||||||
paletteData,
|
paletteData,
|
||||||
nPaletteEntries,
|
nPaletteEntries,
|
||||||
|
@ -1202,7 +1198,8 @@ k_means(Pixel *pixelData,
|
||||||
goto error_3;
|
goto error_3;
|
||||||
}
|
}
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf (".(%d)",changes);fflush(stdout);
|
printf(".(%d)", changes);
|
||||||
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
if (changes <= threshold) {
|
if (changes <= threshold) {
|
||||||
break;
|
break;
|
||||||
|
@ -1248,14 +1245,14 @@ error_1:
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
quantize(Pixel *pixelData,
|
quantize(
|
||||||
|
Pixel *pixelData,
|
||||||
uint32_t nPixels,
|
uint32_t nPixels,
|
||||||
uint32_t nQuantPixels,
|
uint32_t nQuantPixels,
|
||||||
Pixel **palette,
|
Pixel **palette,
|
||||||
uint32_t *paletteLength,
|
uint32_t *paletteLength,
|
||||||
uint32_t **quantizedPixels,
|
uint32_t **quantizedPixels,
|
||||||
int kmeans)
|
int kmeans) {
|
||||||
{
|
|
||||||
PixelList *hl[3];
|
PixelList *hl[3];
|
||||||
HashTable *h;
|
HashTable *h;
|
||||||
BoxNode *root;
|
BoxNode *root;
|
||||||
|
@ -1273,7 +1270,9 @@ quantize(Pixel *pixelData,
|
||||||
|
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
timer2 = clock();
|
timer2 = clock();
|
||||||
printf ("create hash table..."); fflush(stdout); timer=clock();
|
printf("create hash table...");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
#endif
|
#endif
|
||||||
h = create_pixel_hash(pixelData, nPixels);
|
h = create_pixel_hash(pixelData, nPixels);
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
|
@ -1284,7 +1283,9 @@ quantize(Pixel *pixelData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf ("create lists from hash table..."); fflush(stdout); timer=clock();
|
printf("create lists from hash table...");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
#endif
|
#endif
|
||||||
hl[0] = hl[1] = hl[2] = NULL;
|
hl[0] = hl[1] = hl[2] = NULL;
|
||||||
hashtable_foreach(h, hash_to_list, hl);
|
hashtable_foreach(h, hash_to_list, hl);
|
||||||
|
@ -1297,7 +1298,9 @@ quantize(Pixel *pixelData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf ("mergesort lists..."); fflush(stdout); timer=clock();
|
printf("mergesort lists...");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
hl[i] = mergesort_pixels(hl[i], i);
|
hl[i] = mergesort_pixels(hl[i], i);
|
||||||
|
@ -1313,7 +1316,9 @@ quantize(Pixel *pixelData,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf ("median cut..."); fflush(stdout); timer=clock();
|
printf("median cut...");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
#endif
|
#endif
|
||||||
root = median_cut(hl, nPixels, nQuantPixels);
|
root = median_cut(hl, nPixels, nQuantPixels);
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
|
@ -1324,14 +1329,18 @@ quantize(Pixel *pixelData,
|
||||||
}
|
}
|
||||||
nPaletteEntries = 0;
|
nPaletteEntries = 0;
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf ("median cut tree to hash table..."); fflush(stdout); timer=clock();
|
printf("median cut tree to hash table...");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
#endif
|
#endif
|
||||||
annotate_hash_table(root, h, &nPaletteEntries);
|
annotate_hash_table(root, h, &nPaletteEntries);
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf("done (%f)\n", (clock() - timer) / (double)CLOCKS_PER_SEC);
|
printf("done (%f)\n", (clock() - timer) / (double)CLOCKS_PER_SEC);
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf ("compute palette...\n"); fflush(stdout); timer=clock();
|
printf("compute palette...\n");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
#endif
|
#endif
|
||||||
if (!compute_palette_from_median_cut(pixelData, nPixels, h, &p, nPaletteEntries)) {
|
if (!compute_palette_from_median_cut(pixelData, nPixels, h, &p, nPaletteEntries)) {
|
||||||
goto error_3;
|
goto error_3;
|
||||||
|
@ -1345,24 +1354,31 @@ quantize(Pixel *pixelData,
|
||||||
|
|
||||||
/* malloc check ok, using calloc for overflow */
|
/* malloc check ok, using calloc for overflow */
|
||||||
qp = calloc(nPixels, sizeof(uint32_t));
|
qp = calloc(nPixels, sizeof(uint32_t));
|
||||||
if (!qp) { goto error_4; }
|
if (!qp) {
|
||||||
|
goto error_4;
|
||||||
|
}
|
||||||
|
|
||||||
if (nPaletteEntries > UINT32_MAX / nPaletteEntries) {
|
if (nPaletteEntries > UINT32_MAX / nPaletteEntries) {
|
||||||
goto error_5;
|
goto error_5;
|
||||||
}
|
}
|
||||||
/* malloc check ok, using calloc for overflow, check of n*n above */
|
/* malloc check ok, using calloc for overflow, check of n*n above */
|
||||||
avgDist = calloc(nPaletteEntries * nPaletteEntries, sizeof(uint32_t));
|
avgDist = calloc(nPaletteEntries * nPaletteEntries, sizeof(uint32_t));
|
||||||
if (!avgDist) { goto error_5; }
|
if (!avgDist) {
|
||||||
|
goto error_5;
|
||||||
|
}
|
||||||
|
|
||||||
/* malloc check ok, using calloc for overflow, check of n*n above */
|
/* malloc check ok, using calloc for overflow, check of n*n above */
|
||||||
avgDistSortKey = calloc(nPaletteEntries * nPaletteEntries, sizeof(uint32_t *));
|
avgDistSortKey = calloc(nPaletteEntries * nPaletteEntries, sizeof(uint32_t *));
|
||||||
if (!avgDistSortKey) { goto error_6; }
|
if (!avgDistSortKey) {
|
||||||
|
goto error_6;
|
||||||
|
}
|
||||||
|
|
||||||
if (!build_distance_tables(avgDist, avgDistSortKey, p, nPaletteEntries)) {
|
if (!build_distance_tables(avgDist, avgDistSortKey, p, nPaletteEntries)) {
|
||||||
goto error_7;
|
goto error_7;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!map_image_pixels_from_median_box(pixelData,nPixels,p,nPaletteEntries,h,avgDist,avgDistSortKey,qp)) {
|
if (!map_image_pixels_from_median_box(
|
||||||
|
pixelData, nPixels, p, nPaletteEntries, h, avgDist, avgDistSortKey, qp)) {
|
||||||
goto error_7;
|
goto error_7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1371,20 +1387,20 @@ quantize(Pixel *pixelData,
|
||||||
{
|
{
|
||||||
uint32_t bestmatch, bestdist, dist;
|
uint32_t bestmatch, bestdist, dist;
|
||||||
HashTable *h2;
|
HashTable *h2;
|
||||||
printf ("nearest neighbour search (full search)..."); fflush(stdout); timer=clock();
|
printf("nearest neighbour search (full search)...");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
h2 = hashtable_new(unshifted_pixel_hash, unshifted_pixel_cmp);
|
h2 = hashtable_new(unshifted_pixel_hash, unshifted_pixel_cmp);
|
||||||
for (i = 0; i < nPixels; i++) {
|
for (i = 0; i < nPixels; i++) {
|
||||||
if (hashtable_lookup(h2, pixelData[i], &paletteEntry)) {
|
if (hashtable_lookup(h2, pixelData[i], &paletteEntry)) {
|
||||||
bestmatch = paletteEntry;
|
bestmatch = paletteEntry;
|
||||||
} else {
|
} else {
|
||||||
bestmatch = 0;
|
bestmatch = 0;
|
||||||
bestdist=
|
bestdist = _SQR(pixelData[i].c.r - p[0].c.r) +
|
||||||
_SQR(pixelData[i].c.r-p[0].c.r)+
|
|
||||||
_SQR(pixelData[i].c.g - p[0].c.g) +
|
_SQR(pixelData[i].c.g - p[0].c.g) +
|
||||||
_SQR(pixelData[i].c.b - p[0].c.b);
|
_SQR(pixelData[i].c.b - p[0].c.b);
|
||||||
for (j = 1; j < nPaletteEntries; j++) {
|
for (j = 1; j < nPaletteEntries; j++) {
|
||||||
dist=
|
dist = _SQR(pixelData[i].c.r - p[j].c.r) +
|
||||||
_SQR(pixelData[i].c.r-p[j].c.r)+
|
|
||||||
_SQR(pixelData[i].c.g - p[j].c.g) +
|
_SQR(pixelData[i].c.g - p[j].c.g) +
|
||||||
_SQR(pixelData[i].c.b - p[j].c.b);
|
_SQR(pixelData[i].c.b - p[j].c.b);
|
||||||
if (dist == bestdist && j == qp[i]) {
|
if (dist == bestdist && j == qp[i]) {
|
||||||
|
@ -1413,7 +1429,9 @@ quantize(Pixel *pixelData,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf ("k means...\n"); fflush(stdout); timer=clock();
|
printf("k means...\n");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
#endif
|
#endif
|
||||||
if (kmeans) {
|
if (kmeans) {
|
||||||
k_means(pixelData, nPixels, p, nPaletteEntries, qp, kmeans - 1);
|
k_means(pixelData, nPixels, p, nPaletteEntries, qp, kmeans - 1);
|
||||||
|
@ -1427,7 +1445,9 @@ quantize(Pixel *pixelData,
|
||||||
*paletteLength = nPaletteEntries;
|
*paletteLength = nPaletteEntries;
|
||||||
|
|
||||||
#ifndef NO_OUTPUT
|
#ifndef NO_OUTPUT
|
||||||
printf ("cleanup..."); fflush(stdout); timer=clock();
|
printf("cleanup...");
|
||||||
|
fflush(stdout);
|
||||||
|
timer = clock();
|
||||||
#endif
|
#endif
|
||||||
if (avgDist) {
|
if (avgDist) {
|
||||||
free(avgDist);
|
free(avgDist);
|
||||||
|
@ -1479,8 +1499,7 @@ typedef struct {
|
||||||
} DistanceData;
|
} DistanceData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
compute_distances(const HashTable *h, const Pixel pixel, uint32_t *dist, void *u)
|
compute_distances(const HashTable *h, const Pixel pixel, uint32_t *dist, void *u) {
|
||||||
{
|
|
||||||
DistanceData *data = (DistanceData *)u;
|
DistanceData *data = (DistanceData *)u;
|
||||||
uint32_t oldDist = *dist;
|
uint32_t oldDist = *dist;
|
||||||
uint32_t newDist;
|
uint32_t newDist;
|
||||||
|
@ -1496,14 +1515,14 @@ compute_distances(const HashTable *h, const Pixel pixel, uint32_t *dist, void *u
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
quantize2(Pixel *pixelData,
|
quantize2(
|
||||||
|
Pixel *pixelData,
|
||||||
uint32_t nPixels,
|
uint32_t nPixels,
|
||||||
uint32_t nQuantPixels,
|
uint32_t nQuantPixels,
|
||||||
Pixel **palette,
|
Pixel **palette,
|
||||||
uint32_t *paletteLength,
|
uint32_t *paletteLength,
|
||||||
uint32_t **quantizedPixels,
|
uint32_t **quantizedPixels,
|
||||||
int kmeans)
|
int kmeans) {
|
||||||
{
|
|
||||||
HashTable *h;
|
HashTable *h;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint32_t mean[3];
|
uint32_t mean[3];
|
||||||
|
@ -1541,7 +1560,9 @@ quantize2(Pixel *pixelData,
|
||||||
|
|
||||||
/* malloc check ok, using calloc */
|
/* malloc check ok, using calloc */
|
||||||
qp = calloc(nPixels, sizeof(uint32_t));
|
qp = calloc(nPixels, sizeof(uint32_t));
|
||||||
if (!qp) { goto error_1; }
|
if (!qp) {
|
||||||
|
goto error_1;
|
||||||
|
}
|
||||||
|
|
||||||
if (nQuantPixels > UINT32_MAX / nQuantPixels) {
|
if (nQuantPixels > UINT32_MAX / nQuantPixels) {
|
||||||
goto error_2;
|
goto error_2;
|
||||||
|
@ -1549,17 +1570,22 @@ quantize2(Pixel *pixelData,
|
||||||
|
|
||||||
/* malloc check ok, using calloc for overflow, check of n*n above */
|
/* malloc check ok, using calloc for overflow, check of n*n above */
|
||||||
avgDist = calloc(nQuantPixels * nQuantPixels, sizeof(uint32_t));
|
avgDist = calloc(nQuantPixels * nQuantPixels, sizeof(uint32_t));
|
||||||
if (!avgDist) { goto error_2; }
|
if (!avgDist) {
|
||||||
|
goto error_2;
|
||||||
|
}
|
||||||
|
|
||||||
/* malloc check ok, using calloc for overflow, check of n*n above */
|
/* malloc check ok, using calloc for overflow, check of n*n above */
|
||||||
avgDistSortKey = calloc(nQuantPixels * nQuantPixels, sizeof(uint32_t *));
|
avgDistSortKey = calloc(nQuantPixels * nQuantPixels, sizeof(uint32_t *));
|
||||||
if (!avgDistSortKey) { goto error_3; }
|
if (!avgDistSortKey) {
|
||||||
|
goto error_3;
|
||||||
|
}
|
||||||
|
|
||||||
if (!build_distance_tables(avgDist, avgDistSortKey, p, nQuantPixels)) {
|
if (!build_distance_tables(avgDist, avgDistSortKey, p, nQuantPixels)) {
|
||||||
goto error_4;
|
goto error_4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!map_image_pixels(pixelData,nPixels,p,nQuantPixels,avgDist,avgDistSortKey,qp)) {
|
if (!map_image_pixels(
|
||||||
|
pixelData, nPixels, p, nQuantPixels, avgDist, avgDistSortKey, qp)) {
|
||||||
goto error_4;
|
goto error_4;
|
||||||
}
|
}
|
||||||
if (kmeans) {
|
if (kmeans) {
|
||||||
|
@ -1585,8 +1611,7 @@ error_1:
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
|
ImagingQuantize(Imaging im, int colors, int mode, int kmeans) {
|
||||||
{
|
|
||||||
int i, j;
|
int i, j;
|
||||||
int x, y, v;
|
int x, y, v;
|
||||||
UINT8 *pp;
|
UINT8 *pp;
|
||||||
|
@ -1686,8 +1711,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
|
||||||
&palette,
|
&palette,
|
||||||
&paletteLength,
|
&paletteLength,
|
||||||
&newData,
|
&newData,
|
||||||
kmeans
|
kmeans);
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* maximum coverage */
|
/* maximum coverage */
|
||||||
|
@ -1698,8 +1722,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
|
||||||
&palette,
|
&palette,
|
||||||
&paletteLength,
|
&paletteLength,
|
||||||
&newData,
|
&newData,
|
||||||
kmeans
|
kmeans);
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (!strcmp(im->mode, "RGBA")) {
|
if (!strcmp(im->mode, "RGBA")) {
|
||||||
|
@ -1712,8 +1735,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
|
||||||
&palette,
|
&palette,
|
||||||
&paletteLength,
|
&paletteLength,
|
||||||
&newData,
|
&newData,
|
||||||
withAlpha
|
withAlpha);
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
#ifdef HAVE_LIBIMAGEQUANT
|
#ifdef HAVE_LIBIMAGEQUANT
|
||||||
|
@ -1728,8 +1750,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
|
||||||
&palette,
|
&palette,
|
||||||
&paletteLength,
|
&paletteLength,
|
||||||
&newData,
|
&newData,
|
||||||
withAlpha
|
withAlpha);
|
||||||
);
|
|
||||||
#else
|
#else
|
||||||
result = -1;
|
result = -1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1783,7 +1804,6 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
|
||||||
return imOut;
|
return imOut;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
return (Imaging)ImagingError_ValueError(
|
return (Imaging)ImagingError_ValueError(
|
||||||
"dependency required by this method was not "
|
"dependency required by this method was not "
|
||||||
|
@ -1791,6 +1811,5 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Imaging)ImagingError_ValueError("quantization error");
|
return (Imaging)ImagingError_ValueError("quantization error");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,24 +41,32 @@ struct _HashTable {
|
||||||
#define MIN_LENGTH 11
|
#define MIN_LENGTH 11
|
||||||
#define RESIZE_FACTOR 3
|
#define RESIZE_FACTOR 3
|
||||||
|
|
||||||
static int _hashtable_insert_node(HashTable *,HashNode *,int,int,CollisionFunc);
|
static int
|
||||||
|
_hashtable_insert_node(HashTable *, HashNode *, int, int, CollisionFunc);
|
||||||
|
|
||||||
HashTable *hashtable_new(HashFunc hf,HashCmpFunc cf) {
|
HashTable *
|
||||||
|
hashtable_new(HashFunc hf, HashCmpFunc cf) {
|
||||||
HashTable *h;
|
HashTable *h;
|
||||||
h = malloc(sizeof(HashTable));
|
h = malloc(sizeof(HashTable));
|
||||||
if (!h) { return NULL; }
|
if (!h) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
h->hashFunc = hf;
|
h->hashFunc = hf;
|
||||||
h->cmpFunc = cf;
|
h->cmpFunc = cf;
|
||||||
h->length = MIN_LENGTH;
|
h->length = MIN_LENGTH;
|
||||||
h->count = 0;
|
h->count = 0;
|
||||||
h->userData = NULL;
|
h->userData = NULL;
|
||||||
h->table = malloc(sizeof(HashNode *) * h->length);
|
h->table = malloc(sizeof(HashNode *) * h->length);
|
||||||
if (!h->table) { free(h); return NULL; }
|
if (!h->table) {
|
||||||
|
free(h);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
memset(h->table, 0, sizeof(HashNode *) * h->length);
|
memset(h->table, 0, sizeof(HashNode *) * h->length);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t _findPrime(uint32_t start,int dir) {
|
static uint32_t
|
||||||
|
_findPrime(uint32_t start, int dir) {
|
||||||
static int unit[] = {0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0};
|
static int unit[] = {0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0};
|
||||||
uint32_t t;
|
uint32_t t;
|
||||||
while (start > 1) {
|
while (start > 1) {
|
||||||
|
@ -79,7 +87,8 @@ static uint32_t _findPrime(uint32_t start,int dir) {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _hashtable_rehash(HashTable *h,CollisionFunc cf,uint32_t newSize) {
|
static void
|
||||||
|
_hashtable_rehash(HashTable *h, CollisionFunc cf, uint32_t newSize) {
|
||||||
HashNode **oldTable = h->table;
|
HashNode **oldTable = h->table;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
HashNode *n, *nn;
|
HashNode *n, *nn;
|
||||||
|
@ -102,7 +111,8 @@ static void _hashtable_rehash(HashTable *h,CollisionFunc cf,uint32_t newSize) {
|
||||||
free(oldTable);
|
free(oldTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _hashtable_resize(HashTable *h) {
|
static void
|
||||||
|
_hashtable_resize(HashTable *h) {
|
||||||
uint32_t newSize;
|
uint32_t newSize;
|
||||||
uint32_t oldSize;
|
uint32_t oldSize;
|
||||||
oldSize = h->length;
|
oldSize = h->length;
|
||||||
|
@ -112,13 +122,17 @@ static void _hashtable_resize(HashTable *h) {
|
||||||
} else if (h->length * RESIZE_FACTOR < h->count) {
|
} else if (h->length * RESIZE_FACTOR < h->count) {
|
||||||
newSize = _findPrime(h->length * 2 + 1, +1);
|
newSize = _findPrime(h->length * 2 + 1, +1);
|
||||||
}
|
}
|
||||||
if (newSize<MIN_LENGTH) { newSize=oldSize; }
|
if (newSize < MIN_LENGTH) {
|
||||||
|
newSize = oldSize;
|
||||||
|
}
|
||||||
if (newSize != oldSize) {
|
if (newSize != oldSize) {
|
||||||
_hashtable_rehash(h, NULL, newSize);
|
_hashtable_rehash(h, NULL, newSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _hashtable_insert_node(HashTable *h,HashNode *node,int resize,int update,CollisionFunc cf) {
|
static int
|
||||||
|
_hashtable_insert_node(
|
||||||
|
HashTable *h, HashNode *node, int resize, int update, CollisionFunc cf) {
|
||||||
uint32_t hash = h->hashFunc(h, node->key) % h->length;
|
uint32_t hash = h->hashFunc(h, node->key) % h->length;
|
||||||
HashNode **n, *nv;
|
HashNode **n, *nv;
|
||||||
int i;
|
int i;
|
||||||
|
@ -155,7 +169,8 @@ static int _hashtable_insert_node(HashTable *h,HashNode *node,int resize,int upd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val,int resize,int update) {
|
static int
|
||||||
|
_hashtable_insert(HashTable *h, HashKey_t key, HashVal_t val, int resize, int update) {
|
||||||
HashNode **n, *nv;
|
HashNode **n, *nv;
|
||||||
HashNode *t;
|
HashNode *t;
|
||||||
int i;
|
int i;
|
||||||
|
@ -190,10 +205,9 @@ static int _hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val,int resize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashtable_insert_or_update_computed(HashTable *h,
|
int
|
||||||
HashKey_t key,
|
hashtable_insert_or_update_computed(
|
||||||
ComputeFunc newFunc,
|
HashTable *h, HashKey_t key, ComputeFunc newFunc, ComputeFunc existsFunc) {
|
||||||
ComputeFunc existsFunc) {
|
|
||||||
HashNode **n, *nv;
|
HashNode **n, *nv;
|
||||||
HashNode *t;
|
HashNode *t;
|
||||||
int i;
|
int i;
|
||||||
|
@ -231,11 +245,13 @@ int hashtable_insert_or_update_computed(HashTable *h,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val) {
|
int
|
||||||
|
hashtable_insert(HashTable *h, HashKey_t key, HashVal_t val) {
|
||||||
return _hashtable_insert(h, key, val, 1, 0);
|
return _hashtable_insert(h, key, val, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashtable_foreach_update(HashTable *h,IteratorUpdateFunc i,void *u) {
|
void
|
||||||
|
hashtable_foreach_update(HashTable *h, IteratorUpdateFunc i, void *u) {
|
||||||
HashNode *n;
|
HashNode *n;
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
|
|
||||||
|
@ -248,7 +264,8 @@ void hashtable_foreach_update(HashTable *h,IteratorUpdateFunc i,void *u) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashtable_foreach(HashTable *h,IteratorFunc i,void *u) {
|
void
|
||||||
|
hashtable_foreach(HashTable *h, IteratorFunc i, void *u) {
|
||||||
HashNode *n;
|
HashNode *n;
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
|
|
||||||
|
@ -261,7 +278,8 @@ void hashtable_foreach(HashTable *h,IteratorFunc i,void *u) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashtable_free(HashTable *h) {
|
void
|
||||||
|
hashtable_free(HashTable *h) {
|
||||||
HashNode *n, *nn;
|
HashNode *n, *nn;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
|
@ -277,11 +295,13 @@ void hashtable_free(HashTable *h) {
|
||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashtable_rehash_compute(HashTable *h,CollisionFunc cf) {
|
void
|
||||||
|
hashtable_rehash_compute(HashTable *h, CollisionFunc cf) {
|
||||||
_hashtable_rehash(h, cf, h->length);
|
_hashtable_rehash(h, cf, h->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashtable_lookup(const HashTable *h,const HashKey_t key,HashVal_t *valp) {
|
int
|
||||||
|
hashtable_lookup(const HashTable *h, const HashKey_t key, HashVal_t *valp) {
|
||||||
uint32_t hash = h->hashFunc(h, key) % h->length;
|
uint32_t hash = h->hashFunc(h, key) % h->length;
|
||||||
HashNode *n;
|
HashNode *n;
|
||||||
int i;
|
int i;
|
||||||
|
@ -298,15 +318,18 @@ int hashtable_lookup(const HashTable *h,const HashKey_t key,HashVal_t *valp) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t hashtable_get_count(const HashTable *h) {
|
uint32_t
|
||||||
|
hashtable_get_count(const HashTable *h) {
|
||||||
return h->count;
|
return h->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hashtable_get_user_data(const HashTable *h) {
|
void *
|
||||||
|
hashtable_get_user_data(const HashTable *h) {
|
||||||
return h->userData;
|
return h->userData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hashtable_set_user_data(HashTable *h,void *data) {
|
void *
|
||||||
|
hashtable_set_user_data(HashTable *h, void *data) {
|
||||||
void *r = h->userData;
|
void *r = h->userData;
|
||||||
h->userData = data;
|
h->userData = data;
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -20,21 +20,36 @@ typedef uint32_t HashVal_t;
|
||||||
|
|
||||||
typedef uint32_t (*HashFunc)(const HashTable *, const HashKey_t);
|
typedef uint32_t (*HashFunc)(const HashTable *, const HashKey_t);
|
||||||
typedef int (*HashCmpFunc)(const HashTable *, const HashKey_t, const HashKey_t);
|
typedef int (*HashCmpFunc)(const HashTable *, const HashKey_t, const HashKey_t);
|
||||||
typedef void (*IteratorFunc)(const HashTable *,const HashKey_t,const HashVal_t,void *);
|
typedef void (*IteratorFunc)(
|
||||||
typedef void (*IteratorUpdateFunc)(const HashTable *,const HashKey_t,HashVal_t *,void *);
|
const HashTable *, const HashKey_t, const HashVal_t, void *);
|
||||||
|
typedef void (*IteratorUpdateFunc)(
|
||||||
|
const HashTable *, const HashKey_t, HashVal_t *, void *);
|
||||||
typedef void (*ComputeFunc)(const HashTable *, const HashKey_t, HashVal_t *);
|
typedef void (*ComputeFunc)(const HashTable *, const HashKey_t, HashVal_t *);
|
||||||
typedef void (*CollisionFunc)(const HashTable *,HashKey_t *,HashVal_t *,HashKey_t,HashVal_t);
|
typedef void (*CollisionFunc)(
|
||||||
|
const HashTable *, HashKey_t *, HashVal_t *, HashKey_t, HashVal_t);
|
||||||
|
|
||||||
HashTable * hashtable_new(HashFunc hf,HashCmpFunc cf);
|
HashTable *
|
||||||
void hashtable_free(HashTable *h);
|
hashtable_new(HashFunc hf, HashCmpFunc cf);
|
||||||
void hashtable_foreach(HashTable *h,IteratorFunc i,void *u);
|
void
|
||||||
void hashtable_foreach_update(HashTable *h,IteratorUpdateFunc i,void *u);
|
hashtable_free(HashTable *h);
|
||||||
int hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val);
|
void
|
||||||
int hashtable_lookup(const HashTable *h,const HashKey_t key,HashVal_t *valp);
|
hashtable_foreach(HashTable *h, IteratorFunc i, void *u);
|
||||||
int hashtable_insert_or_update_computed(HashTable *h,HashKey_t key,ComputeFunc newFunc,ComputeFunc existsFunc);
|
void
|
||||||
void *hashtable_set_user_data(HashTable *h,void *data);
|
hashtable_foreach_update(HashTable *h, IteratorUpdateFunc i, void *u);
|
||||||
void *hashtable_get_user_data(const HashTable *h);
|
int
|
||||||
uint32_t hashtable_get_count(const HashTable *h);
|
hashtable_insert(HashTable *h, HashKey_t key, HashVal_t val);
|
||||||
void hashtable_rehash_compute(HashTable *h,CollisionFunc cf);
|
int
|
||||||
|
hashtable_lookup(const HashTable *h, const HashKey_t key, HashVal_t *valp);
|
||||||
|
int
|
||||||
|
hashtable_insert_or_update_computed(
|
||||||
|
HashTable *h, HashKey_t key, ComputeFunc newFunc, ComputeFunc existsFunc);
|
||||||
|
void *
|
||||||
|
hashtable_set_user_data(HashTable *h, void *data);
|
||||||
|
void *
|
||||||
|
hashtable_get_user_data(const HashTable *h);
|
||||||
|
uint32_t
|
||||||
|
hashtable_get_count(const HashTable *h);
|
||||||
|
void
|
||||||
|
hashtable_rehash_compute(HashTable *h, CollisionFunc cf);
|
||||||
|
|
||||||
#endif // __QUANTHASH_H__
|
#endif // __QUANTHASH_H__
|
||||||
|
|
|
@ -36,15 +36,18 @@ struct _Heap {
|
||||||
// #define DEBUG
|
// #define DEBUG
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int _heap_test(Heap *);
|
static int
|
||||||
|
_heap_test(Heap *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ImagingQuantHeapFree(Heap *h) {
|
void
|
||||||
|
ImagingQuantHeapFree(Heap *h) {
|
||||||
free(h->heap);
|
free(h->heap);
|
||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _heap_grow(Heap *h,unsigned int newsize) {
|
static int
|
||||||
|
_heap_grow(Heap *h, unsigned int newsize) {
|
||||||
void *newheap;
|
void *newheap;
|
||||||
if (!newsize) {
|
if (!newsize) {
|
||||||
newsize = h->heapsize << 1;
|
newsize = h->heapsize << 1;
|
||||||
|
@ -69,7 +72,8 @@ static int _heap_grow(Heap *h,unsigned int newsize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int _heap_test(Heap *h) {
|
static int
|
||||||
|
_heap_test(Heap *h) {
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
for (k = 1; k * 2 <= h->heapcount; k++) {
|
for (k = 1; k * 2 <= h->heapcount; k++) {
|
||||||
if (h->cf(h, h->heap[k], h->heap[k * 2]) < 0) {
|
if (h->cf(h, h->heap[k], h->heap[k * 2]) < 0) {
|
||||||
|
@ -85,7 +89,8 @@ static int _heap_test(Heap *h) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ImagingQuantHeapRemove(Heap* h,void **r) {
|
int
|
||||||
|
ImagingQuantHeapRemove(Heap *h, void **r) {
|
||||||
unsigned int k, l;
|
unsigned int k, l;
|
||||||
void *v;
|
void *v;
|
||||||
|
|
||||||
|
@ -108,12 +113,16 @@ int ImagingQuantHeapRemove(Heap* h,void **r) {
|
||||||
}
|
}
|
||||||
h->heap[k] = v;
|
h->heap[k] = v;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (!_heap_test(h)) { printf ("oops - heap_remove messed up the heap\n"); exit(1); }
|
if (!_heap_test(h)) {
|
||||||
|
printf("oops - heap_remove messed up the heap\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImagingQuantHeapAdd(Heap *h,void *val) {
|
int
|
||||||
|
ImagingQuantHeapAdd(Heap *h, void *val) {
|
||||||
int k;
|
int k;
|
||||||
if (h->heapcount == h->heapsize - 1) {
|
if (h->heapcount == h->heapsize - 1) {
|
||||||
_heap_grow(h, 0);
|
_heap_grow(h, 0);
|
||||||
|
@ -128,12 +137,16 @@ int ImagingQuantHeapAdd(Heap *h,void *val) {
|
||||||
}
|
}
|
||||||
h->heap[k] = val;
|
h->heap[k] = val;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (!_heap_test(h)) { printf ("oops - heap_add messed up the heap\n"); exit(1); }
|
if (!_heap_test(h)) {
|
||||||
|
printf("oops - heap_add messed up the heap\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImagingQuantHeapTop(Heap *h,void **r) {
|
int
|
||||||
|
ImagingQuantHeapTop(Heap *h, void **r) {
|
||||||
if (!h->heapcount) {
|
if (!h->heapcount) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +154,8 @@ int ImagingQuantHeapTop(Heap *h,void **r) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Heap *ImagingQuantHeapNew(HeapCmpFunc cf) {
|
Heap *
|
||||||
|
ImagingQuantHeapNew(HeapCmpFunc cf) {
|
||||||
Heap *h;
|
Heap *h;
|
||||||
|
|
||||||
/* malloc check ok, small constant allocation */
|
/* malloc check ok, small constant allocation */
|
||||||
|
|
|
@ -18,10 +18,14 @@ typedef struct _Heap Heap;
|
||||||
|
|
||||||
typedef int (*HeapCmpFunc)(const Heap *, const void *, const void *);
|
typedef int (*HeapCmpFunc)(const Heap *, const void *, const void *);
|
||||||
|
|
||||||
void ImagingQuantHeapFree(Heap *);
|
void
|
||||||
int ImagingQuantHeapRemove(Heap *,void **);
|
ImagingQuantHeapFree(Heap *);
|
||||||
int ImagingQuantHeapAdd(Heap *,void *);
|
int
|
||||||
int ImagingQuantHeapTop(Heap *,void **);
|
ImagingQuantHeapRemove(Heap *, void **);
|
||||||
|
int
|
||||||
|
ImagingQuantHeapAdd(Heap *, void *);
|
||||||
|
int
|
||||||
|
ImagingQuantHeapTop(Heap *, void **);
|
||||||
Heap *ImagingQuantHeapNew(HeapCmpFunc);
|
Heap *ImagingQuantHeapNew(HeapCmpFunc);
|
||||||
|
|
||||||
#endif // __QUANTHEAP_H__
|
#endif // __QUANTHEAP_H__
|
||||||
|
|
|
@ -106,10 +106,14 @@ free_color_cube(ColorCube cube) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
color_bucket_offset_pos(const ColorCube cube,
|
color_bucket_offset_pos(
|
||||||
unsigned int r, unsigned int g, unsigned int b, unsigned int a)
|
const ColorCube cube,
|
||||||
{
|
unsigned int r,
|
||||||
return r<<cube->rOffset | g<<cube->gOffset | b<<cube->bOffset | a<<cube->aOffset;
|
unsigned int g,
|
||||||
|
unsigned int b,
|
||||||
|
unsigned int a) {
|
||||||
|
return r << cube->rOffset | g << cube->gOffset | b << cube->bOffset |
|
||||||
|
a << cube->aOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
|
@ -183,13 +187,17 @@ create_sorted_color_palette(const ColorCube cube) {
|
||||||
}
|
}
|
||||||
memcpy(buckets, cube->buckets, sizeof(struct _ColorBucket) * cube->size);
|
memcpy(buckets, cube->buckets, sizeof(struct _ColorBucket) * cube->size);
|
||||||
|
|
||||||
qsort(buckets, cube->size, sizeof(struct _ColorBucket),
|
qsort(
|
||||||
|
buckets,
|
||||||
|
cube->size,
|
||||||
|
sizeof(struct _ColorBucket),
|
||||||
(int (*)(void const *, void const *)) & compare_bucket_count);
|
(int (*)(void const *, void const *)) & compare_bucket_count);
|
||||||
|
|
||||||
return buckets;
|
return buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_bucket_values(ColorBucket src, ColorBucket dst) {
|
void
|
||||||
|
add_bucket_values(ColorBucket src, ColorBucket dst) {
|
||||||
dst->count += src->count;
|
dst->count += src->count;
|
||||||
dst->r += src->r;
|
dst->r += src->r;
|
||||||
dst->g += src->g;
|
dst->g += src->g;
|
||||||
|
@ -198,9 +206,13 @@ void add_bucket_values(ColorBucket src, ColorBucket dst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expand or shrink a given cube to level */
|
/* expand or shrink a given cube to level */
|
||||||
static ColorCube copy_color_cube(const ColorCube cube,
|
static ColorCube
|
||||||
unsigned int rBits, unsigned int gBits, unsigned int bBits, unsigned int aBits)
|
copy_color_cube(
|
||||||
{
|
const ColorCube cube,
|
||||||
|
unsigned int rBits,
|
||||||
|
unsigned int gBits,
|
||||||
|
unsigned int bBits,
|
||||||
|
unsigned int aBits) {
|
||||||
unsigned int r, g, b, a;
|
unsigned int r, g, b, a;
|
||||||
long src_pos, dst_pos;
|
long src_pos, dst_pos;
|
||||||
unsigned int src_reduce[4] = {0}, dst_reduce[4] = {0};
|
unsigned int src_reduce[4] = {0}, dst_reduce[4] = {0};
|
||||||
|
@ -245,20 +257,20 @@ static ColorCube copy_color_cube(const ColorCube cube,
|
||||||
for (g = 0; g < width[1]; g++) {
|
for (g = 0; g < width[1]; g++) {
|
||||||
for (b = 0; b < width[2]; b++) {
|
for (b = 0; b < width[2]; b++) {
|
||||||
for (a = 0; a < width[3]; a++) {
|
for (a = 0; a < width[3]; a++) {
|
||||||
src_pos = color_bucket_offset_pos(cube,
|
src_pos = color_bucket_offset_pos(
|
||||||
|
cube,
|
||||||
r >> src_reduce[0],
|
r >> src_reduce[0],
|
||||||
g >> src_reduce[1],
|
g >> src_reduce[1],
|
||||||
b >> src_reduce[2],
|
b >> src_reduce[2],
|
||||||
a >> src_reduce[3]);
|
a >> src_reduce[3]);
|
||||||
dst_pos = color_bucket_offset_pos(result,
|
dst_pos = color_bucket_offset_pos(
|
||||||
|
result,
|
||||||
r >> dst_reduce[0],
|
r >> dst_reduce[0],
|
||||||
g >> dst_reduce[1],
|
g >> dst_reduce[1],
|
||||||
b >> dst_reduce[2],
|
b >> dst_reduce[2],
|
||||||
a >> dst_reduce[3]);
|
a >> dst_reduce[3]);
|
||||||
add_bucket_values(
|
add_bucket_values(
|
||||||
&cube->buckets[src_pos],
|
&cube->buckets[src_pos], &result->buckets[dst_pos]);
|
||||||
&result->buckets[dst_pos]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,7 +313,8 @@ lookup_color(const ColorCube cube, const Pixel *p) {
|
||||||
return bucket->count;
|
return bucket->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_lookup_buckets(ColorCube cube, ColorBucket palette, long nColors, long offset) {
|
void
|
||||||
|
add_lookup_buckets(ColorCube cube, ColorBucket palette, long nColors, long offset) {
|
||||||
long i;
|
long i;
|
||||||
Pixel p;
|
Pixel p;
|
||||||
for (i = offset; i < offset + nColors; i++) {
|
for (i = offset; i < offset + nColors; i++) {
|
||||||
|
@ -311,7 +324,11 @@ void add_lookup_buckets(ColorCube cube, ColorBucket palette, long nColors, long
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorBucket
|
ColorBucket
|
||||||
combined_palette(ColorBucket bucketsA, unsigned long nBucketsA, ColorBucket bucketsB, unsigned long nBucketsB) {
|
combined_palette(
|
||||||
|
ColorBucket bucketsA,
|
||||||
|
unsigned long nBucketsA,
|
||||||
|
ColorBucket bucketsB,
|
||||||
|
unsigned long nBucketsB) {
|
||||||
ColorBucket result;
|
ColorBucket result;
|
||||||
if (nBucketsA > LONG_MAX - nBucketsB ||
|
if (nBucketsA > LONG_MAX - nBucketsB ||
|
||||||
(nBucketsA + nBucketsB) > LONG_MAX / sizeof(struct _ColorBucket)) {
|
(nBucketsA + nBucketsB) > LONG_MAX / sizeof(struct _ColorBucket)) {
|
||||||
|
@ -345,11 +362,11 @@ create_palette_array(const ColorBucket palette, unsigned int paletteLength) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
map_image_pixels(const Pixel *pixelData,
|
map_image_pixels(
|
||||||
|
const Pixel *pixelData,
|
||||||
uint32_t nPixels,
|
uint32_t nPixels,
|
||||||
const ColorCube lookupCube,
|
const ColorCube lookupCube,
|
||||||
uint32_t *pixelArray)
|
uint32_t *pixelArray) {
|
||||||
{
|
|
||||||
long i;
|
long i;
|
||||||
for (i = 0; i < nPixels; i++) {
|
for (i = 0; i < nPixels; i++) {
|
||||||
pixelArray[i] = lookup_color(lookupCube, &pixelData[i]);
|
pixelArray[i] = lookup_color(lookupCube, &pixelData[i]);
|
||||||
|
@ -359,14 +376,15 @@ map_image_pixels(const Pixel *pixelData,
|
||||||
const unsigned int CUBE_LEVELS[8] = {4, 4, 4, 0, 2, 2, 2, 0};
|
const unsigned int CUBE_LEVELS[8] = {4, 4, 4, 0, 2, 2, 2, 0};
|
||||||
const unsigned int CUBE_LEVELS_ALPHA[8] = {3, 4, 3, 3, 2, 2, 2, 2};
|
const unsigned int CUBE_LEVELS_ALPHA[8] = {3, 4, 3, 3, 2, 2, 2, 2};
|
||||||
|
|
||||||
int quantize_octree(Pixel *pixelData,
|
int
|
||||||
|
quantize_octree(
|
||||||
|
Pixel *pixelData,
|
||||||
uint32_t nPixels,
|
uint32_t nPixels,
|
||||||
uint32_t nQuantPixels,
|
uint32_t nQuantPixels,
|
||||||
Pixel **palette,
|
Pixel **palette,
|
||||||
uint32_t *paletteLength,
|
uint32_t *paletteLength,
|
||||||
uint32_t **quantizedPixels,
|
uint32_t **quantizedPixels,
|
||||||
int withAlpha)
|
int withAlpha) {
|
||||||
{
|
|
||||||
ColorCube fineCube = NULL;
|
ColorCube fineCube = NULL;
|
||||||
ColorCube coarseCube = NULL;
|
ColorCube coarseCube = NULL;
|
||||||
ColorCube lookupCube = NULL;
|
ColorCube lookupCube = NULL;
|
||||||
|
@ -381,8 +399,7 @@ int quantize_octree(Pixel *pixelData,
|
||||||
|
|
||||||
if (withAlpha) {
|
if (withAlpha) {
|
||||||
cubeBits = CUBE_LEVELS_ALPHA;
|
cubeBits = CUBE_LEVELS_ALPHA;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
cubeBits = CUBE_LEVELS;
|
cubeBits = CUBE_LEVELS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,8 +419,7 @@ int quantize_octree(Pixel *pixelData,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* create fine cube */
|
/* create fine cube */
|
||||||
fineCube = new_color_cube(cubeBits[0], cubeBits[1],
|
fineCube = new_color_cube(cubeBits[0], cubeBits[1], cubeBits[2], cubeBits[3]);
|
||||||
cubeBits[2], cubeBits[3]);
|
|
||||||
if (!fineCube) {
|
if (!fineCube) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -412,8 +428,8 @@ int quantize_octree(Pixel *pixelData,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create coarse cube */
|
/* create coarse cube */
|
||||||
coarseCube = copy_color_cube(fineCube, cubeBits[4], cubeBits[5],
|
coarseCube =
|
||||||
cubeBits[6], cubeBits[7]);
|
copy_color_cube(fineCube, cubeBits[4], cubeBits[5], cubeBits[6], cubeBits[7]);
|
||||||
if (!coarseCube) {
|
if (!coarseCube) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +458,9 @@ int quantize_octree(Pixel *pixelData,
|
||||||
nAlreadySubtracted = nFineColors;
|
nAlreadySubtracted = nFineColors;
|
||||||
nCoarseColors = count_used_color_buckets(coarseCube);
|
nCoarseColors = count_used_color_buckets(coarseCube);
|
||||||
nFineColors = nQuantPixels - nCoarseColors;
|
nFineColors = nQuantPixels - nCoarseColors;
|
||||||
subtract_color_buckets(coarseCube, &paletteBucketsFine[nAlreadySubtracted],
|
subtract_color_buckets(
|
||||||
|
coarseCube,
|
||||||
|
&paletteBucketsFine[nAlreadySubtracted],
|
||||||
nFineColors - nAlreadySubtracted);
|
nFineColors - nAlreadySubtracted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,8 +469,8 @@ int quantize_octree(Pixel *pixelData,
|
||||||
if (!paletteBucketsCoarse) {
|
if (!paletteBucketsCoarse) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
paletteBuckets = combined_palette(paletteBucketsCoarse, nCoarseColors,
|
paletteBuckets = combined_palette(
|
||||||
paletteBucketsFine, nFineColors);
|
paletteBucketsCoarse, nCoarseColors, paletteBucketsFine, nFineColors);
|
||||||
|
|
||||||
free(paletteBucketsFine);
|
free(paletteBucketsFine);
|
||||||
paletteBucketsFine = NULL;
|
paletteBucketsFine = NULL;
|
||||||
|
@ -463,8 +481,8 @@ int quantize_octree(Pixel *pixelData,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add all coarse colors to our coarse lookup cube. */
|
/* add all coarse colors to our coarse lookup cube. */
|
||||||
coarseLookupCube = new_color_cube(cubeBits[4], cubeBits[5],
|
coarseLookupCube =
|
||||||
cubeBits[6], cubeBits[7]);
|
new_color_cube(cubeBits[4], cubeBits[5], cubeBits[6], cubeBits[7]);
|
||||||
if (!coarseLookupCube) {
|
if (!coarseLookupCube) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -472,8 +490,8 @@ int quantize_octree(Pixel *pixelData,
|
||||||
|
|
||||||
/* expand coarse cube (64) to larger fine cube (4k). the value of each
|
/* expand coarse cube (64) to larger fine cube (4k). the value of each
|
||||||
coarse bucket is then present in the according 64 fine buckets. */
|
coarse bucket is then present in the according 64 fine buckets. */
|
||||||
lookupCube = copy_color_cube(coarseLookupCube, cubeBits[0], cubeBits[1],
|
lookupCube = copy_color_cube(
|
||||||
cubeBits[2], cubeBits[3]);
|
coarseLookupCube, cubeBits[0], cubeBits[1], cubeBits[2], cubeBits[3]);
|
||||||
if (!lookupCube) {
|
if (!lookupCube) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,7 @@
|
||||||
|
|
||||||
#include "QuantTypes.h"
|
#include "QuantTypes.h"
|
||||||
|
|
||||||
int quantize_octree(Pixel *,
|
int
|
||||||
uint32_t,
|
quantize_octree(Pixel *, uint32_t, uint32_t, Pixel **, uint32_t *, uint32_t **, int);
|
||||||
uint32_t,
|
|
||||||
Pixel **,
|
|
||||||
uint32_t *,
|
|
||||||
uint32_t **,
|
|
||||||
int);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,8 +26,7 @@ quantize_pngquant(
|
||||||
Pixel **palette,
|
Pixel **palette,
|
||||||
uint32_t *paletteLength,
|
uint32_t *paletteLength,
|
||||||
uint32_t **quantizedPixels,
|
uint32_t **quantizedPixels,
|
||||||
int withAlpha)
|
int withAlpha) {
|
||||||
{
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
liq_image *image = NULL;
|
liq_image *image = NULL;
|
||||||
liq_attr *attr = NULL;
|
liq_attr *attr = NULL;
|
||||||
|
@ -41,23 +40,24 @@ quantize_pngquant(
|
||||||
|
|
||||||
/* configure pngquant */
|
/* configure pngquant */
|
||||||
attr = liq_attr_create();
|
attr = liq_attr_create();
|
||||||
if (!attr) { goto err; }
|
if (!attr) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
if (quantPixels) {
|
if (quantPixels) {
|
||||||
liq_set_max_colors(attr, quantPixels);
|
liq_set_max_colors(attr, quantPixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare input image */
|
/* prepare input image */
|
||||||
image = liq_image_create_rgba(
|
image = liq_image_create_rgba(attr, pixelData, width, height, 0.45455 /* gamma */);
|
||||||
attr,
|
if (!image) {
|
||||||
pixelData,
|
goto err;
|
||||||
width,
|
}
|
||||||
height,
|
|
||||||
0.45455 /* gamma */);
|
|
||||||
if (!image) { goto err; }
|
|
||||||
|
|
||||||
/* quantize the image */
|
/* quantize the image */
|
||||||
remap = liq_quantize_image(attr, image);
|
remap = liq_quantize_image(attr, image);
|
||||||
if (!remap) { goto err; }
|
if (!remap) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
liq_set_output_gamma(remap, 0.45455);
|
liq_set_output_gamma(remap, 0.45455);
|
||||||
liq_set_dithering_level(remap, 1);
|
liq_set_dithering_level(remap, 1);
|
||||||
|
|
||||||
|
@ -65,7 +65,9 @@ quantize_pngquant(
|
||||||
const liq_palette *l_palette = liq_get_palette(remap);
|
const liq_palette *l_palette = liq_get_palette(remap);
|
||||||
*paletteLength = l_palette->count;
|
*paletteLength = l_palette->count;
|
||||||
*palette = malloc(sizeof(Pixel) * l_palette->count);
|
*palette = malloc(sizeof(Pixel) * l_palette->count);
|
||||||
if (!*palette) { goto err; }
|
if (!*palette) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
for (i = 0; i < l_palette->count; i++) {
|
for (i = 0; i < l_palette->count; i++) {
|
||||||
(*palette)[i].c.b = l_palette->entries[i].b;
|
(*palette)[i].c.b = l_palette->entries[i].b;
|
||||||
(*palette)[i].c.g = l_palette->entries[i].g;
|
(*palette)[i].c.g = l_palette->entries[i].g;
|
||||||
|
@ -75,9 +77,13 @@ quantize_pngquant(
|
||||||
|
|
||||||
/* write output pixels (pngquant uses char array) */
|
/* write output pixels (pngquant uses char array) */
|
||||||
charMatrix = malloc(width * height);
|
charMatrix = malloc(width * height);
|
||||||
if (!charMatrix) { goto err; }
|
if (!charMatrix) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
charMatrixRows = malloc(height * sizeof(unsigned char *));
|
charMatrixRows = malloc(height * sizeof(unsigned char *));
|
||||||
if (!charMatrixRows) { goto err; }
|
if (!charMatrixRows) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
for (y = 0; y < height; y++) {
|
for (y = 0; y < height; y++) {
|
||||||
charMatrixRows[y] = &charMatrix[y * width];
|
charMatrixRows[y] = &charMatrix[y * width];
|
||||||
}
|
}
|
||||||
|
@ -87,7 +93,9 @@ quantize_pngquant(
|
||||||
|
|
||||||
/* transcribe output pixels (pillow uses uint32_t array) */
|
/* transcribe output pixels (pillow uses uint32_t array) */
|
||||||
*quantizedPixels = malloc(sizeof(uint32_t) * width * height);
|
*quantizedPixels = malloc(sizeof(uint32_t) * width * height);
|
||||||
if (!*quantizedPixels) { goto err; }
|
if (!*quantizedPixels) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
for (i = 0; i < width * height; i++) {
|
for (i = 0; i < width * height; i++) {
|
||||||
(*quantizedPixels)[i] = charMatrix[i];
|
(*quantizedPixels)[i] = charMatrix[i];
|
||||||
}
|
}
|
||||||
|
@ -114,8 +122,7 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
ImagingImageQuantVersion(void)
|
ImagingImageQuantVersion(void) {
|
||||||
{
|
|
||||||
static char version[20];
|
static char version[20];
|
||||||
int number = liq_version();
|
int number = liq_version();
|
||||||
sprintf(version, "%d.%d.%d", number / 10000, (number / 100) % 100, number % 100);
|
sprintf(version, "%d.%d.%d", number / 10000, (number / 100) % 100, number % 100);
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
|
|
||||||
#include "QuantTypes.h"
|
#include "QuantTypes.h"
|
||||||
|
|
||||||
int quantize_pngquant(Pixel *,
|
int
|
||||||
|
quantize_pngquant(
|
||||||
|
Pixel *,
|
||||||
unsigned int,
|
unsigned int,
|
||||||
unsigned int,
|
unsigned int,
|
||||||
uint32_t,
|
uint32_t,
|
||||||
|
|
|
@ -17,14 +17,19 @@
|
||||||
/* Fast rank algorithm (due to Wirth), based on public domain code
|
/* Fast rank algorithm (due to Wirth), based on public domain code
|
||||||
by Nicolas Devillard, available at http://ndevilla.free.fr */
|
by Nicolas Devillard, available at http://ndevilla.free.fr */
|
||||||
|
|
||||||
#define SWAP(type,a,b) { register type t=(a);(a)=(b);(b)=t; }
|
#define SWAP(type, a, b) \
|
||||||
|
{ \
|
||||||
|
register type t = (a); \
|
||||||
|
(a) = (b); \
|
||||||
|
(b) = t; \
|
||||||
|
}
|
||||||
|
|
||||||
#define MakeRankFunction(type) \
|
#define MakeRankFunction(type) \
|
||||||
static type Rank##type(type a[], int n, int k)\
|
static type Rank##type(type a[], int n, int k) { \
|
||||||
{\
|
|
||||||
register int i, j, l, m; \
|
register int i, j, l, m; \
|
||||||
register type x; \
|
register type x; \
|
||||||
l = 0; m = n-1;\
|
l = 0; \
|
||||||
|
m = n - 1; \
|
||||||
while (l < m) { \
|
while (l < m) { \
|
||||||
x = a[k]; \
|
x = a[k]; \
|
||||||
i = l; \
|
i = l; \
|
||||||
|
@ -38,7 +43,8 @@ static type Rank##type(type a[], int n, int k)\
|
||||||
} \
|
} \
|
||||||
if (i <= j) { \
|
if (i <= j) { \
|
||||||
SWAP(type, a[i], a[j]); \
|
SWAP(type, a[i], a[j]); \
|
||||||
i++; j--;\
|
i++; \
|
||||||
|
j--; \
|
||||||
} \
|
} \
|
||||||
} while (i <= j); \
|
} while (i <= j); \
|
||||||
if (j < k) { \
|
if (j < k) { \
|
||||||
|
@ -51,13 +57,9 @@ static type Rank##type(type a[], int n, int k)\
|
||||||
return a[k]; \
|
return a[k]; \
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeRankFunction(UINT8)
|
MakeRankFunction(UINT8) MakeRankFunction(INT32) MakeRankFunction(FLOAT32)
|
||||||
MakeRankFunction(INT32)
|
|
||||||
MakeRankFunction(FLOAT32)
|
|
||||||
|
|
||||||
Imaging
|
Imaging ImagingRankFilter(Imaging im, int size, int rank) {
|
||||||
ImagingRankFilter(Imaging im, int size, int rank)
|
|
||||||
{
|
|
||||||
Imaging imOut = NULL;
|
Imaging imOut = NULL;
|
||||||
int x, y;
|
int x, y;
|
||||||
int i, margin, size2;
|
int i, margin, size2;
|
||||||
|
@ -71,8 +73,7 @@ ImagingRankFilter(Imaging im, int size, int rank)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* malloc check ok, for overflow in the define below */
|
/* malloc check ok, for overflow in the define below */
|
||||||
if (size > INT_MAX / size ||
|
if (size > INT_MAX / size || size > INT_MAX / (size * (int)sizeof(FLOAT32))) {
|
||||||
size > INT_MAX / (size * (int)sizeof(FLOAT32))) {
|
|
||||||
return (Imaging)ImagingError_ValueError("filter size too large");
|
return (Imaging)ImagingError_ValueError("filter size too large");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +90,8 @@ ImagingRankFilter(Imaging im, int size, int rank)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* malloc check ok, checked above */
|
/* malloc check ok, checked above */
|
||||||
#define RANK_BODY(type) do {\
|
#define RANK_BODY(type) \
|
||||||
|
do { \
|
||||||
type *buf = malloc(size2 * sizeof(type)); \
|
type *buf = malloc(size2 * sizeof(type)); \
|
||||||
if (!buf) { \
|
if (!buf) { \
|
||||||
goto nomemory; \
|
goto nomemory; \
|
||||||
|
@ -97,7 +99,9 @@ ImagingRankFilter(Imaging im, int size, int rank)
|
||||||
for (y = 0; y < imOut->ysize; y++) { \
|
for (y = 0; y < imOut->ysize; y++) { \
|
||||||
for (x = 0; x < imOut->xsize; x++) { \
|
for (x = 0; x < imOut->xsize; x++) { \
|
||||||
for (i = 0; i < size; i++) { \
|
for (i = 0; i < size; i++) { \
|
||||||
memcpy(buf + i*size, &IMAGING_PIXEL_##type(im, x, y+i),\
|
memcpy( \
|
||||||
|
buf + i * size, \
|
||||||
|
&IMAGING_PIXEL_##type(im, x, y + i), \
|
||||||
size * sizeof(type)); \
|
size * sizeof(type)); \
|
||||||
} \
|
} \
|
||||||
IMAGING_PIXEL_##type(imOut, x, y) = Rank##type(buf, size2, rank); \
|
IMAGING_PIXEL_##type(imOut, x, y) = Rank##type(buf, size2, rank); \
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* Raw.h */
|
/* Raw.h */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* CONFIGURATION */
|
/* CONFIGURATION */
|
||||||
|
|
||||||
/* Distance between lines (0=no padding) */
|
/* Distance between lines (0=no padding) */
|
||||||
|
|
|
@ -13,22 +13,18 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#include "Raw.h"
|
#include "Raw.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
enum { LINE = 1, SKIP };
|
enum { LINE = 1, SKIP };
|
||||||
RAWSTATE *rawstate = state->context;
|
RAWSTATE *rawstate = state->context;
|
||||||
|
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
|
|
||||||
if (state->state == 0) {
|
if (state->state == 0) {
|
||||||
|
|
||||||
/* Initialize context variables */
|
/* Initialize context variables */
|
||||||
|
|
||||||
/* get size of image data and padding */
|
/* get size of image data and padding */
|
||||||
|
@ -52,15 +48,12 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
}
|
}
|
||||||
|
|
||||||
state->state = LINE;
|
state->state = LINE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (state->state == SKIP) {
|
if (state->state == SKIP) {
|
||||||
|
|
||||||
/* Skip padding between lines */
|
/* Skip padding between lines */
|
||||||
|
|
||||||
if (bytes < rawstate->skip) {
|
if (bytes < rawstate->skip) {
|
||||||
|
@ -71,7 +64,6 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
bytes -= rawstate->skip;
|
bytes -= rawstate->skip;
|
||||||
|
|
||||||
state->state = LINE;
|
state->state = LINE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes < state->bytes) {
|
if (bytes < state->bytes) {
|
||||||
|
@ -79,8 +71,10 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unpack data */
|
/* Unpack data */
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
state->shuffle(
|
||||||
state->xoff * im->pixelsize, ptr, state->xsize);
|
(UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize,
|
||||||
|
ptr,
|
||||||
|
state->xsize);
|
||||||
|
|
||||||
ptr += state->bytes;
|
ptr += state->bytes;
|
||||||
bytes -= state->bytes;
|
bytes -= state->bytes;
|
||||||
|
@ -93,7 +87,5 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
}
|
}
|
||||||
|
|
||||||
state->state = SKIP;
|
state->state = SKIP;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,13 @@
|
||||||
*
|
*
|
||||||
* See the README file for information on usage and redistribution. */
|
* See the README file for information on usage and redistribution. */
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
|
|
||||||
if (!state->state) {
|
if (!state->state) {
|
||||||
|
|
||||||
/* The "count" field holds the stride, if specified. Fix
|
/* The "count" field holds the stride, if specified. Fix
|
||||||
things up so "bytes" is the full size, and "count" the
|
things up so "bytes" is the full size, and "count" the
|
||||||
packed size */
|
packed size */
|
||||||
|
@ -55,7 +52,6 @@ ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes < state->bytes) {
|
if (bytes < state->bytes) {
|
||||||
|
@ -66,9 +62,10 @@ ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
while (bytes >= state->bytes) {
|
while (bytes >= state->bytes) {
|
||||||
|
state->shuffle(
|
||||||
state->shuffle(ptr, (UINT8*) im->image[state->y + state->yoff] +
|
ptr,
|
||||||
state->xoff * im->pixelsize, state->xsize);
|
(UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize,
|
||||||
|
state->xsize);
|
||||||
|
|
||||||
if (state->bytes > state->count) {
|
if (state->bytes > state->count) {
|
||||||
/* zero-pad the buffer, if necessary */
|
/* zero-pad the buffer, if necessary */
|
||||||
|
@ -84,9 +81,7 @@ ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
state->errcode = IMAGING_CODEC_END;
|
state->errcode = IMAGING_CODEC_END;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,15 @@
|
||||||
|
|
||||||
#define ROUND_UP(f) ((int)((f) >= 0.0 ? (f) + 0.5F : (f)-0.5F))
|
#define ROUND_UP(f) ((int)((f) >= 0.0 ? (f) + 0.5F : (f)-0.5F))
|
||||||
|
|
||||||
|
|
||||||
UINT32
|
UINT32
|
||||||
division_UINT32(int divider, int result_bits)
|
division_UINT32(int divider, int result_bits) {
|
||||||
{
|
|
||||||
UINT32 max_dividend = (1 << result_bits) * divider;
|
UINT32 max_dividend = (1 << result_bits) * divider;
|
||||||
float max_int = (1 << 30) * 4.0;
|
float max_int = (1 << 30) * 4.0;
|
||||||
return (UINT32)(max_int / max_dividend);
|
return (UINT32)(max_int / max_dividend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale)
|
ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale) {
|
||||||
{
|
|
||||||
/* The most general implementation for any xscale and yscale
|
/* The most general implementation for any xscale and yscale
|
||||||
*/
|
*/
|
||||||
int x, y, xx, yy;
|
int x, y, xx, yy;
|
||||||
|
@ -33,8 +29,8 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
|
||||||
UINT8 *line0 = (UINT8 *)imIn->image8[yy];
|
UINT8 *line0 = (UINT8 *)imIn->image8[yy];
|
||||||
UINT8 *line1 = (UINT8 *)imIn->image8[yy + 1];
|
UINT8 *line1 = (UINT8 *)imIn->image8[yy + 1];
|
||||||
for (xx = xx_from; xx < xx_from + xscale - 1; xx += 2) {
|
for (xx = xx_from; xx < xx_from + xscale - 1; xx += 2) {
|
||||||
ss += line0[xx + 0] + line0[xx + 1] +
|
ss += line0[xx + 0] + line0[xx + 1] + line1[xx + 0] +
|
||||||
line1[xx + 0] + line1[xx + 1];
|
line1[xx + 1];
|
||||||
}
|
}
|
||||||
if (xscale & 0x01) {
|
if (xscale & 0x01) {
|
||||||
ss += line0[xx + 0] + line1[xx + 0];
|
ss += line0[xx + 0] + line1[xx + 0];
|
||||||
|
@ -86,8 +82,7 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, 0,
|
(ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24);
|
||||||
0, (ss3 * multiplier) >> 24);
|
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
|
@ -126,8 +121,10 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, 0);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
|
@ -171,8 +168,10 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, (ss3 * multiplier) >> 24);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
(ss3 * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,10 +179,8 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale)
|
ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale) {
|
||||||
{
|
|
||||||
/* Optimized implementation for xscale = 1.
|
/* Optimized implementation for xscale = 1.
|
||||||
*/
|
*/
|
||||||
int x, y, yy;
|
int x, y, yy;
|
||||||
|
@ -229,8 +226,7 @@ ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale)
|
||||||
ss3 += line[xx * 4 + 3];
|
ss3 += line[xx * 4 + 3];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, 0,
|
(ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24);
|
||||||
0, (ss3 * multiplier) >> 24);
|
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
|
@ -252,8 +248,10 @@ ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale)
|
||||||
ss2 += line[xx * 4 + 2];
|
ss2 += line[xx * 4 + 2];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, 0);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
|
@ -277,8 +275,10 @@ ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale)
|
||||||
ss3 += line[xx * 4 + 3];
|
ss3 += line[xx * 4 + 3];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, (ss3 * multiplier) >> 24);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
(ss3 * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,10 +286,8 @@ ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale)
|
ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale) {
|
||||||
{
|
|
||||||
/* Optimized implementation for yscale = 1.
|
/* Optimized implementation for yscale = 1.
|
||||||
*/
|
*/
|
||||||
int x, y, xx;
|
int x, y, xx;
|
||||||
|
@ -331,8 +329,7 @@ ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale)
|
||||||
ss3 += line[xx * 4 + 3];
|
ss3 += line[xx * 4 + 3];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, 0,
|
(ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24);
|
||||||
0, (ss3 * multiplier) >> 24);
|
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
|
@ -351,8 +348,10 @@ ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale)
|
||||||
ss2 += line[xx * 4 + 2];
|
ss2 += line[xx * 4 + 2];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, 0);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
|
@ -373,8 +372,10 @@ ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale)
|
||||||
ss3 += line[xx * 4 + 3];
|
ss3 += line[xx * 4 + 3];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, (ss3 * multiplier) >> 24);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
(ss3 * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,8 +384,7 @@ ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce1x2(Imaging imOut, Imaging imIn, int box[4])
|
ImagingReduce1x2(Imaging imOut, Imaging imIn, int box[4]) {
|
||||||
{
|
|
||||||
/* Optimized implementation for xscale = 1 and yscale = 2.
|
/* Optimized implementation for xscale = 1 and yscale = 2.
|
||||||
*/
|
*/
|
||||||
int xscale = 1, yscale = 2;
|
int xscale = 1, yscale = 2;
|
||||||
|
@ -399,8 +399,7 @@ ImagingReduce1x2(Imaging imOut, Imaging imIn, int box[4])
|
||||||
UINT8 *line1 = (UINT8 *)imIn->image8[yy + 1];
|
UINT8 *line1 = (UINT8 *)imIn->image8[yy + 1];
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
ss0 = line0[xx + 0] +
|
ss0 = line0[xx + 0] + line1[xx + 0];
|
||||||
line1[xx + 0];
|
|
||||||
imOut->image8[y][x] = (ss0 + amend) >> 1;
|
imOut->image8[y][x] = (ss0 + amend) >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,42 +412,35 @@ ImagingReduce1x2(Imaging imOut, Imaging imIn, int box[4])
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] +
|
ss0 = line0[xx * 4 + 0] + line1[xx * 4 + 0];
|
||||||
line1[xx*4 + 0];
|
ss3 = line0[xx * 4 + 3] + line1[xx * 4 + 3];
|
||||||
ss3 = line0[xx*4 + 3] +
|
v = MAKE_UINT32((ss0 + amend) >> 1, 0, 0, (ss3 + amend) >> 1);
|
||||||
line1[xx*4 + 3];
|
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 1, 0,
|
|
||||||
0, (ss3 + amend) >> 1);
|
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] +
|
ss0 = line0[xx * 4 + 0] + line1[xx * 4 + 0];
|
||||||
line1[xx*4 + 0];
|
ss1 = line0[xx * 4 + 1] + line1[xx * 4 + 1];
|
||||||
ss1 = line0[xx*4 + 1] +
|
ss2 = line0[xx * 4 + 2] + line1[xx * 4 + 2];
|
||||||
line1[xx*4 + 1];
|
v = MAKE_UINT32(
|
||||||
ss2 = line0[xx*4 + 2] +
|
(ss0 + amend) >> 1, (ss1 + amend) >> 1, (ss2 + amend) >> 1, 0);
|
||||||
line1[xx*4 + 2];
|
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 1, (ss1 + amend) >> 1,
|
|
||||||
(ss2 + amend) >> 1, 0);
|
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] +
|
ss0 = line0[xx * 4 + 0] + line1[xx * 4 + 0];
|
||||||
line1[xx*4 + 0];
|
ss1 = line0[xx * 4 + 1] + line1[xx * 4 + 1];
|
||||||
ss1 = line0[xx*4 + 1] +
|
ss2 = line0[xx * 4 + 2] + line1[xx * 4 + 2];
|
||||||
line1[xx*4 + 1];
|
ss3 = line0[xx * 4 + 3] + line1[xx * 4 + 3];
|
||||||
ss2 = line0[xx*4 + 2] +
|
v = MAKE_UINT32(
|
||||||
line1[xx*4 + 2];
|
(ss0 + amend) >> 1,
|
||||||
ss3 = line0[xx*4 + 3] +
|
(ss1 + amend) >> 1,
|
||||||
line1[xx*4 + 3];
|
(ss2 + amend) >> 1,
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 1, (ss1 + amend) >> 1,
|
(ss3 + amend) >> 1);
|
||||||
(ss2 + amend) >> 1, (ss3 + amend) >> 1);
|
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,10 +448,8 @@ ImagingReduce1x2(Imaging imOut, Imaging imIn, int box[4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce2x1(Imaging imOut, Imaging imIn, int box[4])
|
ImagingReduce2x1(Imaging imOut, Imaging imIn, int box[4]) {
|
||||||
{
|
|
||||||
/* Optimized implementation for xscale = 2 and yscale = 1.
|
/* Optimized implementation for xscale = 2 and yscale = 1.
|
||||||
*/
|
*/
|
||||||
int xscale = 2, yscale = 1;
|
int xscale = 2, yscale = 1;
|
||||||
|
@ -487,8 +477,7 @@ ImagingReduce2x1(Imaging imOut, Imaging imIn, int box[4])
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4];
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4];
|
||||||
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7];
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7];
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 1, 0,
|
v = MAKE_UINT32((ss0 + amend) >> 1, 0, 0, (ss3 + amend) >> 1);
|
||||||
0, (ss3 + amend) >> 1);
|
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
|
@ -498,8 +487,8 @@ ImagingReduce2x1(Imaging imOut, Imaging imIn, int box[4])
|
||||||
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4];
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4];
|
||||||
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5];
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5];
|
||||||
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6];
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6];
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 1, (ss1 + amend) >> 1,
|
v = MAKE_UINT32(
|
||||||
(ss2 + amend) >> 1, 0);
|
(ss0 + amend) >> 1, (ss1 + amend) >> 1, (ss2 + amend) >> 1, 0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
|
@ -510,8 +499,11 @@ ImagingReduce2x1(Imaging imOut, Imaging imIn, int box[4])
|
||||||
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5];
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5];
|
||||||
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6];
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6];
|
||||||
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7];
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7];
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 1, (ss1 + amend) >> 1,
|
v = MAKE_UINT32(
|
||||||
(ss2 + amend) >> 1, (ss3 + amend) >> 1);
|
(ss0 + amend) >> 1,
|
||||||
|
(ss1 + amend) >> 1,
|
||||||
|
(ss2 + amend) >> 1,
|
||||||
|
(ss3 + amend) >> 1);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -519,10 +511,8 @@ ImagingReduce2x1(Imaging imOut, Imaging imIn, int box[4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce2x2(Imaging imOut, Imaging imIn, int box[4])
|
ImagingReduce2x2(Imaging imOut, Imaging imIn, int box[4]) {
|
||||||
{
|
|
||||||
/* Optimized implementation for xscale = 2 and yscale = 2.
|
/* Optimized implementation for xscale = 2 and yscale = 2.
|
||||||
*/
|
*/
|
||||||
int xscale = 2, yscale = 2;
|
int xscale = 2, yscale = 2;
|
||||||
|
@ -537,8 +527,7 @@ ImagingReduce2x2(Imaging imOut, Imaging imIn, int box[4])
|
||||||
UINT8 *line1 = (UINT8 *)imIn->image8[yy + 1];
|
UINT8 *line1 = (UINT8 *)imIn->image8[yy + 1];
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
ss0 = line0[xx + 0] + line0[xx + 1] +
|
ss0 = line0[xx + 0] + line0[xx + 1] + line1[xx + 0] + line1[xx + 1];
|
||||||
line1[xx + 0] + line1[xx + 1];
|
|
||||||
imOut->image8[y][x] = (ss0 + amend) >> 2;
|
imOut->image8[y][x] = (ss0 + amend) >> 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -551,42 +540,44 @@ ImagingReduce2x2(Imaging imOut, Imaging imIn, int box[4])
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line1[xx * 4 + 0] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4];
|
line1[xx * 4 + 4];
|
||||||
ss3 = line0[xx*4 + 3] + line0[xx*4 + 7] +
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line1[xx * 4 + 3] +
|
||||||
line1[xx*4 + 3] + line1[xx*4 + 7];
|
line1[xx * 4 + 7];
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 2, 0,
|
v = MAKE_UINT32((ss0 + amend) >> 2, 0, 0, (ss3 + amend) >> 2);
|
||||||
0, (ss3 + amend) >> 2);
|
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line1[xx * 4 + 0] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4];
|
line1[xx * 4 + 4];
|
||||||
ss1 = line0[xx*4 + 1] + line0[xx*4 + 5] +
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5] + line1[xx * 4 + 1] +
|
||||||
line1[xx*4 + 1] + line1[xx*4 + 5];
|
line1[xx * 4 + 5];
|
||||||
ss2 = line0[xx*4 + 2] + line0[xx*4 + 6] +
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line1[xx * 4 + 2] +
|
||||||
line1[xx*4 + 2] + line1[xx*4 + 6];
|
line1[xx * 4 + 6];
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 2, (ss1 + amend) >> 2,
|
v = MAKE_UINT32(
|
||||||
(ss2 + amend) >> 2, 0);
|
(ss0 + amend) >> 2, (ss1 + amend) >> 2, (ss2 + amend) >> 2, 0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line1[xx * 4 + 0] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4];
|
line1[xx * 4 + 4];
|
||||||
ss1 = line0[xx*4 + 1] + line0[xx*4 + 5] +
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5] + line1[xx * 4 + 1] +
|
||||||
line1[xx*4 + 1] + line1[xx*4 + 5];
|
line1[xx * 4 + 5];
|
||||||
ss2 = line0[xx*4 + 2] + line0[xx*4 + 6] +
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line1[xx * 4 + 2] +
|
||||||
line1[xx*4 + 2] + line1[xx*4 + 6];
|
line1[xx * 4 + 6];
|
||||||
ss3 = line0[xx*4 + 3] + line0[xx*4 + 7] +
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line1[xx * 4 + 3] +
|
||||||
line1[xx*4 + 3] + line1[xx*4 + 7];
|
line1[xx * 4 + 7];
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 2, (ss1 + amend) >> 2,
|
v = MAKE_UINT32(
|
||||||
(ss2 + amend) >> 2, (ss3 + amend) >> 2);
|
(ss0 + amend) >> 2,
|
||||||
|
(ss1 + amend) >> 2,
|
||||||
|
(ss2 + amend) >> 2,
|
||||||
|
(ss3 + amend) >> 2);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -594,10 +585,8 @@ ImagingReduce2x2(Imaging imOut, Imaging imIn, int box[4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce1x3(Imaging imOut, Imaging imIn, int box[4])
|
ImagingReduce1x3(Imaging imOut, Imaging imIn, int box[4]) {
|
||||||
{
|
|
||||||
/* Optimized implementation for xscale = 1 and yscale = 3.
|
/* Optimized implementation for xscale = 1 and yscale = 3.
|
||||||
*/
|
*/
|
||||||
int xscale = 1, yscale = 3;
|
int xscale = 1, yscale = 3;
|
||||||
|
@ -614,9 +603,7 @@ ImagingReduce1x3(Imaging imOut, Imaging imIn, int box[4])
|
||||||
UINT8 *line2 = (UINT8 *)imIn->image8[yy + 2];
|
UINT8 *line2 = (UINT8 *)imIn->image8[yy + 2];
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
ss0 = line0[xx + 0] +
|
ss0 = line0[xx + 0] + line1[xx + 0] + line2[xx + 0];
|
||||||
line1[xx + 0] +
|
|
||||||
line2[xx + 0];
|
|
||||||
imOut->image8[y][x] = ((ss0 + amend) * multiplier) >> 24;
|
imOut->image8[y][x] = ((ss0 + amend) * multiplier) >> 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -630,54 +617,42 @@ ImagingReduce1x3(Imaging imOut, Imaging imIn, int box[4])
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] +
|
ss0 = line0[xx * 4 + 0] + line1[xx * 4 + 0] + line2[xx * 4 + 0];
|
||||||
line1[xx*4 + 0] +
|
ss3 = line0[xx * 4 + 3] + line1[xx * 4 + 3] + line2[xx * 4 + 3];
|
||||||
line2[xx*4 + 0];
|
|
||||||
ss3 = line0[xx*4 + 3] +
|
|
||||||
line1[xx*4 + 3] +
|
|
||||||
line2[xx*4 + 3];
|
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, 0,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
0, ((ss3 + amend) * multiplier) >> 24);
|
0,
|
||||||
|
0,
|
||||||
|
((ss3 + amend) * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] +
|
ss0 = line0[xx * 4 + 0] + line1[xx * 4 + 0] + line2[xx * 4 + 0];
|
||||||
line1[xx*4 + 0] +
|
ss1 = line0[xx * 4 + 1] + line1[xx * 4 + 1] + line2[xx * 4 + 1];
|
||||||
line2[xx*4 + 0];
|
ss2 = line0[xx * 4 + 2] + line1[xx * 4 + 2] + line2[xx * 4 + 2];
|
||||||
ss1 = line0[xx*4 + 1] +
|
|
||||||
line1[xx*4 + 1] +
|
|
||||||
line2[xx*4 + 1];
|
|
||||||
ss2 = line0[xx*4 + 2] +
|
|
||||||
line1[xx*4 + 2] +
|
|
||||||
line2[xx*4 + 2];
|
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
((ss2 + amend) * multiplier) >> 24, 0);
|
((ss1 + amend) * multiplier) >> 24,
|
||||||
|
((ss2 + amend) * multiplier) >> 24,
|
||||||
|
0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] +
|
ss0 = line0[xx * 4 + 0] + line1[xx * 4 + 0] + line2[xx * 4 + 0];
|
||||||
line1[xx*4 + 0] +
|
ss1 = line0[xx * 4 + 1] + line1[xx * 4 + 1] + line2[xx * 4 + 1];
|
||||||
line2[xx*4 + 0];
|
ss2 = line0[xx * 4 + 2] + line1[xx * 4 + 2] + line2[xx * 4 + 2];
|
||||||
ss1 = line0[xx*4 + 1] +
|
ss3 = line0[xx * 4 + 3] + line1[xx * 4 + 3] + line2[xx * 4 + 3];
|
||||||
line1[xx*4 + 1] +
|
|
||||||
line2[xx*4 + 1];
|
|
||||||
ss2 = line0[xx*4 + 2] +
|
|
||||||
line1[xx*4 + 2] +
|
|
||||||
line2[xx*4 + 2];
|
|
||||||
ss3 = line0[xx*4 + 3] +
|
|
||||||
line1[xx*4 + 3] +
|
|
||||||
line2[xx*4 + 3];
|
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
((ss2 + amend) * multiplier) >> 24, ((ss3 + amend) * multiplier) >> 24);
|
((ss1 + amend) * multiplier) >> 24,
|
||||||
|
((ss2 + amend) * multiplier) >> 24,
|
||||||
|
((ss3 + amend) * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,10 +660,8 @@ ImagingReduce1x3(Imaging imOut, Imaging imIn, int box[4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4])
|
ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4]) {
|
||||||
{
|
|
||||||
/* Optimized implementation for xscale = 3 and yscale = 1.
|
/* Optimized implementation for xscale = 3 and yscale = 1.
|
||||||
*/
|
*/
|
||||||
int xscale = 3, yscale = 1;
|
int xscale = 3, yscale = 1;
|
||||||
|
@ -718,8 +691,10 @@ ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4])
|
||||||
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line0[xx * 4 + 8];
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line0[xx * 4 + 8];
|
||||||
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line0[xx * 4 + 11];
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line0[xx * 4 + 11];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, 0,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
0, ((ss3 + amend) * multiplier) >> 24);
|
0,
|
||||||
|
0,
|
||||||
|
((ss3 + amend) * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
|
@ -730,8 +705,10 @@ ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4])
|
||||||
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5] + line0[xx * 4 + 9];
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5] + line0[xx * 4 + 9];
|
||||||
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line0[xx * 4 + 10];
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line0[xx * 4 + 10];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
((ss2 + amend) * multiplier) >> 24, 0);
|
((ss1 + amend) * multiplier) >> 24,
|
||||||
|
((ss2 + amend) * multiplier) >> 24,
|
||||||
|
0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
|
@ -743,8 +720,10 @@ ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4])
|
||||||
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line0[xx * 4 + 10];
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line0[xx * 4 + 10];
|
||||||
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line0[xx * 4 + 11];
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line0[xx * 4 + 11];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
((ss2 + amend) * multiplier) >> 24, ((ss3 + amend) * multiplier) >> 24);
|
((ss1 + amend) * multiplier) >> 24,
|
||||||
|
((ss2 + amend) * multiplier) >> 24,
|
||||||
|
((ss3 + amend) * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -752,10 +731,8 @@ ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4])
|
ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4]) {
|
||||||
{
|
|
||||||
/* Optimized implementation for xscale = 3 and yscale = 3.
|
/* Optimized implementation for xscale = 3 and yscale = 3.
|
||||||
*/
|
*/
|
||||||
int xscale = 3, yscale = 3;
|
int xscale = 3, yscale = 3;
|
||||||
|
@ -772,9 +749,9 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4])
|
||||||
UINT8 *line2 = (UINT8 *)imIn->image8[yy + 2];
|
UINT8 *line2 = (UINT8 *)imIn->image8[yy + 2];
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
ss0 = line0[xx + 0] + line0[xx + 1] + line0[xx + 2] +
|
ss0 = line0[xx + 0] + line0[xx + 1] + line0[xx + 2] + line1[xx + 0] +
|
||||||
line1[xx + 0] + line1[xx + 1] + line1[xx + 2] +
|
line1[xx + 1] + line1[xx + 2] + line2[xx + 0] + line2[xx + 1] +
|
||||||
line2[xx + 0] + line2[xx + 1] + line2[xx + 2];
|
line2[xx + 2];
|
||||||
imOut->image8[y][x] = ((ss0 + amend) * multiplier) >> 24;
|
imOut->image8[y][x] = ((ss0 + amend) * multiplier) >> 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -795,8 +772,10 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4])
|
||||||
line1[xx * 4 + 3] + line1[xx * 4 + 7] + line1[xx * 4 + 11] +
|
line1[xx * 4 + 3] + line1[xx * 4 + 7] + line1[xx * 4 + 11] +
|
||||||
line2[xx * 4 + 3] + line2[xx * 4 + 7] + line2[xx * 4 + 11];
|
line2[xx * 4 + 3] + line2[xx * 4 + 7] + line2[xx * 4 + 11];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, 0,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
0, ((ss3 + amend) * multiplier) >> 24);
|
0,
|
||||||
|
0,
|
||||||
|
((ss3 + amend) * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
|
@ -813,8 +792,10 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4])
|
||||||
line1[xx * 4 + 2] + line1[xx * 4 + 6] + line1[xx * 4 + 10] +
|
line1[xx * 4 + 2] + line1[xx * 4 + 6] + line1[xx * 4 + 10] +
|
||||||
line2[xx * 4 + 2] + line2[xx * 4 + 6] + line2[xx * 4 + 10];
|
line2[xx * 4 + 2] + line2[xx * 4 + 6] + line2[xx * 4 + 10];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
((ss2 + amend) * multiplier) >> 24, 0);
|
((ss1 + amend) * multiplier) >> 24,
|
||||||
|
((ss2 + amend) * multiplier) >> 24,
|
||||||
|
0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
|
@ -834,8 +815,10 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4])
|
||||||
line1[xx * 4 + 3] + line1[xx * 4 + 7] + line1[xx * 4 + 11] +
|
line1[xx * 4 + 3] + line1[xx * 4 + 7] + line1[xx * 4 + 11] +
|
||||||
line2[xx * 4 + 3] + line2[xx * 4 + 7] + line2[xx * 4 + 11];
|
line2[xx * 4 + 3] + line2[xx * 4 + 7] + line2[xx * 4 + 11];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
((ss2 + amend) * multiplier) >> 24, ((ss3 + amend) * multiplier) >> 24);
|
((ss1 + amend) * multiplier) >> 24,
|
||||||
|
((ss2 + amend) * multiplier) >> 24,
|
||||||
|
((ss3 + amend) * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -844,8 +827,7 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4])
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce4x4(Imaging imOut, Imaging imIn, int box[4])
|
ImagingReduce4x4(Imaging imOut, Imaging imIn, int box[4]) {
|
||||||
{
|
|
||||||
/* Optimized implementation for xscale = 4 and yscale = 4.
|
/* Optimized implementation for xscale = 4 and yscale = 4.
|
||||||
*/
|
*/
|
||||||
int xscale = 4, yscale = 4;
|
int xscale = 4, yscale = 4;
|
||||||
|
@ -880,60 +862,80 @@ ImagingReduce4x4(Imaging imOut, Imaging imIn, int box[4])
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + line0[xx*4 + 12] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line0[xx * 4 + 8] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + line1[xx*4 + 12] +
|
line0[xx * 4 + 12] + line1[xx * 4 + 0] + line1[xx * 4 + 4] +
|
||||||
line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8] + line2[xx*4 + 12] +
|
line1[xx * 4 + 8] + line1[xx * 4 + 12] + line2[xx * 4 + 0] +
|
||||||
line3[xx*4 + 0] + line3[xx*4 + 4] + line3[xx*4 + 8] + line3[xx*4 + 12];
|
line2[xx * 4 + 4] + line2[xx * 4 + 8] + line2[xx * 4 + 12] +
|
||||||
ss3 = line0[xx*4 + 3] + line0[xx*4 + 7] + line0[xx*4 + 11] + line0[xx*4 + 15] +
|
line3[xx * 4 + 0] + line3[xx * 4 + 4] + line3[xx * 4 + 8] +
|
||||||
line1[xx*4 + 3] + line1[xx*4 + 7] + line1[xx*4 + 11] + line1[xx*4 + 15] +
|
line3[xx * 4 + 12];
|
||||||
line2[xx*4 + 3] + line2[xx*4 + 7] + line2[xx*4 + 11] + line2[xx*4 + 15] +
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line0[xx * 4 + 11] +
|
||||||
line3[xx*4 + 3] + line3[xx*4 + 7] + line3[xx*4 + 11] + line3[xx*4 + 15];
|
line0[xx * 4 + 15] + line1[xx * 4 + 3] + line1[xx * 4 + 7] +
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 4, 0,
|
line1[xx * 4 + 11] + line1[xx * 4 + 15] + line2[xx * 4 + 3] +
|
||||||
0, (ss3 + amend) >> 4);
|
line2[xx * 4 + 7] + line2[xx * 4 + 11] + line2[xx * 4 + 15] +
|
||||||
|
line3[xx * 4 + 3] + line3[xx * 4 + 7] + line3[xx * 4 + 11] +
|
||||||
|
line3[xx * 4 + 15];
|
||||||
|
v = MAKE_UINT32((ss0 + amend) >> 4, 0, 0, (ss3 + amend) >> 4);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + line0[xx*4 + 12] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line0[xx * 4 + 8] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + line1[xx*4 + 12] +
|
line0[xx * 4 + 12] + line1[xx * 4 + 0] + line1[xx * 4 + 4] +
|
||||||
line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8] + line2[xx*4 + 12] +
|
line1[xx * 4 + 8] + line1[xx * 4 + 12] + line2[xx * 4 + 0] +
|
||||||
line3[xx*4 + 0] + line3[xx*4 + 4] + line3[xx*4 + 8] + line3[xx*4 + 12];
|
line2[xx * 4 + 4] + line2[xx * 4 + 8] + line2[xx * 4 + 12] +
|
||||||
ss1 = line0[xx*4 + 1] + line0[xx*4 + 5] + line0[xx*4 + 9] + line0[xx*4 + 13] +
|
line3[xx * 4 + 0] + line3[xx * 4 + 4] + line3[xx * 4 + 8] +
|
||||||
line1[xx*4 + 1] + line1[xx*4 + 5] + line1[xx*4 + 9] + line1[xx*4 + 13] +
|
line3[xx * 4 + 12];
|
||||||
line2[xx*4 + 1] + line2[xx*4 + 5] + line2[xx*4 + 9] + line2[xx*4 + 13] +
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5] + line0[xx * 4 + 9] +
|
||||||
line3[xx*4 + 1] + line3[xx*4 + 5] + line3[xx*4 + 9] + line3[xx*4 + 13];
|
line0[xx * 4 + 13] + line1[xx * 4 + 1] + line1[xx * 4 + 5] +
|
||||||
ss2 = line0[xx*4 + 2] + line0[xx*4 + 6] + line0[xx*4 + 10] + line0[xx*4 + 14] +
|
line1[xx * 4 + 9] + line1[xx * 4 + 13] + line2[xx * 4 + 1] +
|
||||||
line1[xx*4 + 2] + line1[xx*4 + 6] + line1[xx*4 + 10] + line1[xx*4 + 14] +
|
line2[xx * 4 + 5] + line2[xx * 4 + 9] + line2[xx * 4 + 13] +
|
||||||
line2[xx*4 + 2] + line2[xx*4 + 6] + line2[xx*4 + 10] + line2[xx*4 + 14] +
|
line3[xx * 4 + 1] + line3[xx * 4 + 5] + line3[xx * 4 + 9] +
|
||||||
line3[xx*4 + 2] + line3[xx*4 + 6] + line3[xx*4 + 10] + line3[xx*4 + 14];
|
line3[xx * 4 + 13];
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 4, (ss1 + amend) >> 4,
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line0[xx * 4 + 10] +
|
||||||
(ss2 + amend) >> 4, 0);
|
line0[xx * 4 + 14] + line1[xx * 4 + 2] + line1[xx * 4 + 6] +
|
||||||
|
line1[xx * 4 + 10] + line1[xx * 4 + 14] + line2[xx * 4 + 2] +
|
||||||
|
line2[xx * 4 + 6] + line2[xx * 4 + 10] + line2[xx * 4 + 14] +
|
||||||
|
line3[xx * 4 + 2] + line3[xx * 4 + 6] + line3[xx * 4 + 10] +
|
||||||
|
line3[xx * 4 + 14];
|
||||||
|
v = MAKE_UINT32(
|
||||||
|
(ss0 + amend) >> 4, (ss1 + amend) >> 4, (ss2 + amend) >> 4, 0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + line0[xx*4 + 12] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line0[xx * 4 + 8] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + line1[xx*4 + 12] +
|
line0[xx * 4 + 12] + line1[xx * 4 + 0] + line1[xx * 4 + 4] +
|
||||||
line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8] + line2[xx*4 + 12] +
|
line1[xx * 4 + 8] + line1[xx * 4 + 12] + line2[xx * 4 + 0] +
|
||||||
line3[xx*4 + 0] + line3[xx*4 + 4] + line3[xx*4 + 8] + line3[xx*4 + 12];
|
line2[xx * 4 + 4] + line2[xx * 4 + 8] + line2[xx * 4 + 12] +
|
||||||
ss1 = line0[xx*4 + 1] + line0[xx*4 + 5] + line0[xx*4 + 9] + line0[xx*4 + 13] +
|
line3[xx * 4 + 0] + line3[xx * 4 + 4] + line3[xx * 4 + 8] +
|
||||||
line1[xx*4 + 1] + line1[xx*4 + 5] + line1[xx*4 + 9] + line1[xx*4 + 13] +
|
line3[xx * 4 + 12];
|
||||||
line2[xx*4 + 1] + line2[xx*4 + 5] + line2[xx*4 + 9] + line2[xx*4 + 13] +
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5] + line0[xx * 4 + 9] +
|
||||||
line3[xx*4 + 1] + line3[xx*4 + 5] + line3[xx*4 + 9] + line3[xx*4 + 13];
|
line0[xx * 4 + 13] + line1[xx * 4 + 1] + line1[xx * 4 + 5] +
|
||||||
ss2 = line0[xx*4 + 2] + line0[xx*4 + 6] + line0[xx*4 + 10] + line0[xx*4 + 14] +
|
line1[xx * 4 + 9] + line1[xx * 4 + 13] + line2[xx * 4 + 1] +
|
||||||
line1[xx*4 + 2] + line1[xx*4 + 6] + line1[xx*4 + 10] + line1[xx*4 + 14] +
|
line2[xx * 4 + 5] + line2[xx * 4 + 9] + line2[xx * 4 + 13] +
|
||||||
line2[xx*4 + 2] + line2[xx*4 + 6] + line2[xx*4 + 10] + line2[xx*4 + 14] +
|
line3[xx * 4 + 1] + line3[xx * 4 + 5] + line3[xx * 4 + 9] +
|
||||||
line3[xx*4 + 2] + line3[xx*4 + 6] + line3[xx*4 + 10] + line3[xx*4 + 14];
|
line3[xx * 4 + 13];
|
||||||
ss3 = line0[xx*4 + 3] + line0[xx*4 + 7] + line0[xx*4 + 11] + line0[xx*4 + 15] +
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line0[xx * 4 + 10] +
|
||||||
line1[xx*4 + 3] + line1[xx*4 + 7] + line1[xx*4 + 11] + line1[xx*4 + 15] +
|
line0[xx * 4 + 14] + line1[xx * 4 + 2] + line1[xx * 4 + 6] +
|
||||||
line2[xx*4 + 3] + line2[xx*4 + 7] + line2[xx*4 + 11] + line2[xx*4 + 15] +
|
line1[xx * 4 + 10] + line1[xx * 4 + 14] + line2[xx * 4 + 2] +
|
||||||
line3[xx*4 + 3] + line3[xx*4 + 7] + line3[xx*4 + 11] + line3[xx*4 + 15];
|
line2[xx * 4 + 6] + line2[xx * 4 + 10] + line2[xx * 4 + 14] +
|
||||||
v = MAKE_UINT32((ss0 + amend) >> 4, (ss1 + amend) >> 4,
|
line3[xx * 4 + 2] + line3[xx * 4 + 6] + line3[xx * 4 + 10] +
|
||||||
(ss2 + amend) >> 4, (ss3 + amend) >> 4);
|
line3[xx * 4 + 14];
|
||||||
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line0[xx * 4 + 11] +
|
||||||
|
line0[xx * 4 + 15] + line1[xx * 4 + 3] + line1[xx * 4 + 7] +
|
||||||
|
line1[xx * 4 + 11] + line1[xx * 4 + 15] + line2[xx * 4 + 3] +
|
||||||
|
line2[xx * 4 + 7] + line2[xx * 4 + 11] + line2[xx * 4 + 15] +
|
||||||
|
line3[xx * 4 + 3] + line3[xx * 4 + 7] + line3[xx * 4 + 11] +
|
||||||
|
line3[xx * 4 + 15];
|
||||||
|
v = MAKE_UINT32(
|
||||||
|
(ss0 + amend) >> 4,
|
||||||
|
(ss1 + amend) >> 4,
|
||||||
|
(ss2 + amend) >> 4,
|
||||||
|
(ss3 + amend) >> 4);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,10 +943,8 @@ ImagingReduce4x4(Imaging imOut, Imaging imIn, int box[4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4])
|
ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4]) {
|
||||||
{
|
|
||||||
/* Fast special case for xscale = 5 and yscale = 5.
|
/* Fast special case for xscale = 5 and yscale = 5.
|
||||||
*/
|
*/
|
||||||
int xscale = 5, yscale = 5;
|
int xscale = 5, yscale = 5;
|
||||||
|
@ -963,11 +963,13 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4])
|
||||||
UINT8 *line4 = (UINT8 *)imIn->image8[yy + 4];
|
UINT8 *line4 = (UINT8 *)imIn->image8[yy + 4];
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
ss0 = line0[xx + 0] + line0[xx + 1] + line0[xx + 2] + line0[xx + 3] + line0[xx + 4] +
|
ss0 = line0[xx + 0] + line0[xx + 1] + line0[xx + 2] + line0[xx + 3] +
|
||||||
line1[xx + 0] + line1[xx + 1] + line1[xx + 2] + line1[xx + 3] + line1[xx + 4] +
|
line0[xx + 4] + line1[xx + 0] + line1[xx + 1] + line1[xx + 2] +
|
||||||
line2[xx + 0] + line2[xx + 1] + line2[xx + 2] + line2[xx + 3] + line2[xx + 4] +
|
line1[xx + 3] + line1[xx + 4] + line2[xx + 0] + line2[xx + 1] +
|
||||||
line3[xx + 0] + line3[xx + 1] + line3[xx + 2] + line3[xx + 3] + line3[xx + 4] +
|
line2[xx + 2] + line2[xx + 3] + line2[xx + 4] + line3[xx + 0] +
|
||||||
line4[xx + 0] + line4[xx + 1] + line4[xx + 2] + line4[xx + 3] + line4[xx + 4];
|
line3[xx + 1] + line3[xx + 2] + line3[xx + 3] + line3[xx + 4] +
|
||||||
|
line4[xx + 0] + line4[xx + 1] + line4[xx + 2] + line4[xx + 3] +
|
||||||
|
line4[xx + 4];
|
||||||
imOut->image8[y][x] = ((ss0 + amend) * multiplier) >> 24;
|
imOut->image8[y][x] = ((ss0 + amend) * multiplier) >> 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -983,72 +985,114 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4])
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + line0[xx*4 + 12] + line0[xx*4 + 16] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line0[xx * 4 + 8] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + line1[xx*4 + 12] + line1[xx*4 + 16] +
|
line0[xx * 4 + 12] + line0[xx * 4 + 16] + line1[xx * 4 + 0] +
|
||||||
line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8] + line2[xx*4 + 12] + line2[xx*4 + 16] +
|
line1[xx * 4 + 4] + line1[xx * 4 + 8] + line1[xx * 4 + 12] +
|
||||||
line3[xx*4 + 0] + line3[xx*4 + 4] + line3[xx*4 + 8] + line3[xx*4 + 12] + line3[xx*4 + 16] +
|
line1[xx * 4 + 16] + line2[xx * 4 + 0] + line2[xx * 4 + 4] +
|
||||||
line4[xx*4 + 0] + line4[xx*4 + 4] + line4[xx*4 + 8] + line4[xx*4 + 12] + line4[xx*4 + 16];
|
line2[xx * 4 + 8] + line2[xx * 4 + 12] + line2[xx * 4 + 16] +
|
||||||
ss3 = line0[xx*4 + 3] + line0[xx*4 + 7] + line0[xx*4 + 11] + line0[xx*4 + 15] + line0[xx*4 + 19] +
|
line3[xx * 4 + 0] + line3[xx * 4 + 4] + line3[xx * 4 + 8] +
|
||||||
line1[xx*4 + 3] + line1[xx*4 + 7] + line1[xx*4 + 11] + line1[xx*4 + 15] + line1[xx*4 + 19] +
|
line3[xx * 4 + 12] + line3[xx * 4 + 16] + line4[xx * 4 + 0] +
|
||||||
line2[xx*4 + 3] + line2[xx*4 + 7] + line2[xx*4 + 11] + line2[xx*4 + 15] + line2[xx*4 + 19] +
|
line4[xx * 4 + 4] + line4[xx * 4 + 8] + line4[xx * 4 + 12] +
|
||||||
line3[xx*4 + 3] + line3[xx*4 + 7] + line3[xx*4 + 11] + line3[xx*4 + 15] + line3[xx*4 + 19] +
|
line4[xx * 4 + 16];
|
||||||
line4[xx*4 + 3] + line4[xx*4 + 7] + line4[xx*4 + 11] + line4[xx*4 + 15] + line4[xx*4 + 19];
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line0[xx * 4 + 11] +
|
||||||
|
line0[xx * 4 + 15] + line0[xx * 4 + 19] + line1[xx * 4 + 3] +
|
||||||
|
line1[xx * 4 + 7] + line1[xx * 4 + 11] + line1[xx * 4 + 15] +
|
||||||
|
line1[xx * 4 + 19] + line2[xx * 4 + 3] + line2[xx * 4 + 7] +
|
||||||
|
line2[xx * 4 + 11] + line2[xx * 4 + 15] + line2[xx * 4 + 19] +
|
||||||
|
line3[xx * 4 + 3] + line3[xx * 4 + 7] + line3[xx * 4 + 11] +
|
||||||
|
line3[xx * 4 + 15] + line3[xx * 4 + 19] + line4[xx * 4 + 3] +
|
||||||
|
line4[xx * 4 + 7] + line4[xx * 4 + 11] + line4[xx * 4 + 15] +
|
||||||
|
line4[xx * 4 + 19];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, 0,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
0, ((ss3 + amend) * multiplier) >> 24);
|
0,
|
||||||
|
0,
|
||||||
|
((ss3 + amend) * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else if (imIn->bands == 3) {
|
} else if (imIn->bands == 3) {
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + line0[xx*4 + 12] + line0[xx*4 + 16] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line0[xx * 4 + 8] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + line1[xx*4 + 12] + line1[xx*4 + 16] +
|
line0[xx * 4 + 12] + line0[xx * 4 + 16] + line1[xx * 4 + 0] +
|
||||||
line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8] + line2[xx*4 + 12] + line2[xx*4 + 16] +
|
line1[xx * 4 + 4] + line1[xx * 4 + 8] + line1[xx * 4 + 12] +
|
||||||
line3[xx*4 + 0] + line3[xx*4 + 4] + line3[xx*4 + 8] + line3[xx*4 + 12] + line3[xx*4 + 16] +
|
line1[xx * 4 + 16] + line2[xx * 4 + 0] + line2[xx * 4 + 4] +
|
||||||
line4[xx*4 + 0] + line4[xx*4 + 4] + line4[xx*4 + 8] + line4[xx*4 + 12] + line4[xx*4 + 16];
|
line2[xx * 4 + 8] + line2[xx * 4 + 12] + line2[xx * 4 + 16] +
|
||||||
ss1 = line0[xx*4 + 1] + line0[xx*4 + 5] + line0[xx*4 + 9] + line0[xx*4 + 13] + line0[xx*4 + 17] +
|
line3[xx * 4 + 0] + line3[xx * 4 + 4] + line3[xx * 4 + 8] +
|
||||||
line1[xx*4 + 1] + line1[xx*4 + 5] + line1[xx*4 + 9] + line1[xx*4 + 13] + line1[xx*4 + 17] +
|
line3[xx * 4 + 12] + line3[xx * 4 + 16] + line4[xx * 4 + 0] +
|
||||||
line2[xx*4 + 1] + line2[xx*4 + 5] + line2[xx*4 + 9] + line2[xx*4 + 13] + line2[xx*4 + 17] +
|
line4[xx * 4 + 4] + line4[xx * 4 + 8] + line4[xx * 4 + 12] +
|
||||||
line3[xx*4 + 1] + line3[xx*4 + 5] + line3[xx*4 + 9] + line3[xx*4 + 13] + line3[xx*4 + 17] +
|
line4[xx * 4 + 16];
|
||||||
line4[xx*4 + 1] + line4[xx*4 + 5] + line4[xx*4 + 9] + line4[xx*4 + 13] + line4[xx*4 + 17];
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5] + line0[xx * 4 + 9] +
|
||||||
ss2 = line0[xx*4 + 2] + line0[xx*4 + 6] + line0[xx*4 + 10] + line0[xx*4 + 14] + line0[xx*4 + 18] +
|
line0[xx * 4 + 13] + line0[xx * 4 + 17] + line1[xx * 4 + 1] +
|
||||||
line1[xx*4 + 2] + line1[xx*4 + 6] + line1[xx*4 + 10] + line1[xx*4 + 14] + line1[xx*4 + 18] +
|
line1[xx * 4 + 5] + line1[xx * 4 + 9] + line1[xx * 4 + 13] +
|
||||||
line2[xx*4 + 2] + line2[xx*4 + 6] + line2[xx*4 + 10] + line2[xx*4 + 14] + line2[xx*4 + 18] +
|
line1[xx * 4 + 17] + line2[xx * 4 + 1] + line2[xx * 4 + 5] +
|
||||||
line3[xx*4 + 2] + line3[xx*4 + 6] + line3[xx*4 + 10] + line3[xx*4 + 14] + line3[xx*4 + 18] +
|
line2[xx * 4 + 9] + line2[xx * 4 + 13] + line2[xx * 4 + 17] +
|
||||||
line4[xx*4 + 2] + line4[xx*4 + 6] + line4[xx*4 + 10] + line4[xx*4 + 14] + line4[xx*4 + 18];
|
line3[xx * 4 + 1] + line3[xx * 4 + 5] + line3[xx * 4 + 9] +
|
||||||
|
line3[xx * 4 + 13] + line3[xx * 4 + 17] + line4[xx * 4 + 1] +
|
||||||
|
line4[xx * 4 + 5] + line4[xx * 4 + 9] + line4[xx * 4 + 13] +
|
||||||
|
line4[xx * 4 + 17];
|
||||||
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line0[xx * 4 + 10] +
|
||||||
|
line0[xx * 4 + 14] + line0[xx * 4 + 18] + line1[xx * 4 + 2] +
|
||||||
|
line1[xx * 4 + 6] + line1[xx * 4 + 10] + line1[xx * 4 + 14] +
|
||||||
|
line1[xx * 4 + 18] + line2[xx * 4 + 2] + line2[xx * 4 + 6] +
|
||||||
|
line2[xx * 4 + 10] + line2[xx * 4 + 14] + line2[xx * 4 + 18] +
|
||||||
|
line3[xx * 4 + 2] + line3[xx * 4 + 6] + line3[xx * 4 + 10] +
|
||||||
|
line3[xx * 4 + 14] + line3[xx * 4 + 18] + line4[xx * 4 + 2] +
|
||||||
|
line4[xx * 4 + 6] + line4[xx * 4 + 10] + line4[xx * 4 + 14] +
|
||||||
|
line4[xx * 4 + 18];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
((ss2 + amend) * multiplier) >> 24, 0);
|
((ss1 + amend) * multiplier) >> 24,
|
||||||
|
((ss2 + amend) * multiplier) >> 24,
|
||||||
|
0);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
} else { // bands == 4
|
} else { // bands == 4
|
||||||
for (x = 0; x < box[2] / xscale; x++) {
|
for (x = 0; x < box[2] / xscale; x++) {
|
||||||
int xx = box[0] + x * xscale;
|
int xx = box[0] + x * xscale;
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + line0[xx*4 + 12] + line0[xx*4 + 16] +
|
ss0 = line0[xx * 4 + 0] + line0[xx * 4 + 4] + line0[xx * 4 + 8] +
|
||||||
line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + line1[xx*4 + 12] + line1[xx*4 + 16] +
|
line0[xx * 4 + 12] + line0[xx * 4 + 16] + line1[xx * 4 + 0] +
|
||||||
line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8] + line2[xx*4 + 12] + line2[xx*4 + 16] +
|
line1[xx * 4 + 4] + line1[xx * 4 + 8] + line1[xx * 4 + 12] +
|
||||||
line3[xx*4 + 0] + line3[xx*4 + 4] + line3[xx*4 + 8] + line3[xx*4 + 12] + line3[xx*4 + 16] +
|
line1[xx * 4 + 16] + line2[xx * 4 + 0] + line2[xx * 4 + 4] +
|
||||||
line4[xx*4 + 0] + line4[xx*4 + 4] + line4[xx*4 + 8] + line4[xx*4 + 12] + line4[xx*4 + 16];
|
line2[xx * 4 + 8] + line2[xx * 4 + 12] + line2[xx * 4 + 16] +
|
||||||
ss1 = line0[xx*4 + 1] + line0[xx*4 + 5] + line0[xx*4 + 9] + line0[xx*4 + 13] + line0[xx*4 + 17] +
|
line3[xx * 4 + 0] + line3[xx * 4 + 4] + line3[xx * 4 + 8] +
|
||||||
line1[xx*4 + 1] + line1[xx*4 + 5] + line1[xx*4 + 9] + line1[xx*4 + 13] + line1[xx*4 + 17] +
|
line3[xx * 4 + 12] + line3[xx * 4 + 16] + line4[xx * 4 + 0] +
|
||||||
line2[xx*4 + 1] + line2[xx*4 + 5] + line2[xx*4 + 9] + line2[xx*4 + 13] + line2[xx*4 + 17] +
|
line4[xx * 4 + 4] + line4[xx * 4 + 8] + line4[xx * 4 + 12] +
|
||||||
line3[xx*4 + 1] + line3[xx*4 + 5] + line3[xx*4 + 9] + line3[xx*4 + 13] + line3[xx*4 + 17] +
|
line4[xx * 4 + 16];
|
||||||
line4[xx*4 + 1] + line4[xx*4 + 5] + line4[xx*4 + 9] + line4[xx*4 + 13] + line4[xx*4 + 17];
|
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5] + line0[xx * 4 + 9] +
|
||||||
ss2 = line0[xx*4 + 2] + line0[xx*4 + 6] + line0[xx*4 + 10] + line0[xx*4 + 14] + line0[xx*4 + 18] +
|
line0[xx * 4 + 13] + line0[xx * 4 + 17] + line1[xx * 4 + 1] +
|
||||||
line1[xx*4 + 2] + line1[xx*4 + 6] + line1[xx*4 + 10] + line1[xx*4 + 14] + line1[xx*4 + 18] +
|
line1[xx * 4 + 5] + line1[xx * 4 + 9] + line1[xx * 4 + 13] +
|
||||||
line2[xx*4 + 2] + line2[xx*4 + 6] + line2[xx*4 + 10] + line2[xx*4 + 14] + line2[xx*4 + 18] +
|
line1[xx * 4 + 17] + line2[xx * 4 + 1] + line2[xx * 4 + 5] +
|
||||||
line3[xx*4 + 2] + line3[xx*4 + 6] + line3[xx*4 + 10] + line3[xx*4 + 14] + line3[xx*4 + 18] +
|
line2[xx * 4 + 9] + line2[xx * 4 + 13] + line2[xx * 4 + 17] +
|
||||||
line4[xx*4 + 2] + line4[xx*4 + 6] + line4[xx*4 + 10] + line4[xx*4 + 14] + line4[xx*4 + 18];
|
line3[xx * 4 + 1] + line3[xx * 4 + 5] + line3[xx * 4 + 9] +
|
||||||
ss3 = line0[xx*4 + 3] + line0[xx*4 + 7] + line0[xx*4 + 11] + line0[xx*4 + 15] + line0[xx*4 + 19] +
|
line3[xx * 4 + 13] + line3[xx * 4 + 17] + line4[xx * 4 + 1] +
|
||||||
line1[xx*4 + 3] + line1[xx*4 + 7] + line1[xx*4 + 11] + line1[xx*4 + 15] + line1[xx*4 + 19] +
|
line4[xx * 4 + 5] + line4[xx * 4 + 9] + line4[xx * 4 + 13] +
|
||||||
line2[xx*4 + 3] + line2[xx*4 + 7] + line2[xx*4 + 11] + line2[xx*4 + 15] + line2[xx*4 + 19] +
|
line4[xx * 4 + 17];
|
||||||
line3[xx*4 + 3] + line3[xx*4 + 7] + line3[xx*4 + 11] + line3[xx*4 + 15] + line3[xx*4 + 19] +
|
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line0[xx * 4 + 10] +
|
||||||
line4[xx*4 + 3] + line4[xx*4 + 7] + line4[xx*4 + 11] + line4[xx*4 + 15] + line4[xx*4 + 19];
|
line0[xx * 4 + 14] + line0[xx * 4 + 18] + line1[xx * 4 + 2] +
|
||||||
|
line1[xx * 4 + 6] + line1[xx * 4 + 10] + line1[xx * 4 + 14] +
|
||||||
|
line1[xx * 4 + 18] + line2[xx * 4 + 2] + line2[xx * 4 + 6] +
|
||||||
|
line2[xx * 4 + 10] + line2[xx * 4 + 14] + line2[xx * 4 + 18] +
|
||||||
|
line3[xx * 4 + 2] + line3[xx * 4 + 6] + line3[xx * 4 + 10] +
|
||||||
|
line3[xx * 4 + 14] + line3[xx * 4 + 18] + line4[xx * 4 + 2] +
|
||||||
|
line4[xx * 4 + 6] + line4[xx * 4 + 10] + line4[xx * 4 + 14] +
|
||||||
|
line4[xx * 4 + 18];
|
||||||
|
ss3 = line0[xx * 4 + 3] + line0[xx * 4 + 7] + line0[xx * 4 + 11] +
|
||||||
|
line0[xx * 4 + 15] + line0[xx * 4 + 19] + line1[xx * 4 + 3] +
|
||||||
|
line1[xx * 4 + 7] + line1[xx * 4 + 11] + line1[xx * 4 + 15] +
|
||||||
|
line1[xx * 4 + 19] + line2[xx * 4 + 3] + line2[xx * 4 + 7] +
|
||||||
|
line2[xx * 4 + 11] + line2[xx * 4 + 15] + line2[xx * 4 + 19] +
|
||||||
|
line3[xx * 4 + 3] + line3[xx * 4 + 7] + line3[xx * 4 + 11] +
|
||||||
|
line3[xx * 4 + 15] + line3[xx * 4 + 19] + line4[xx * 4 + 3] +
|
||||||
|
line4[xx * 4 + 7] + line4[xx * 4 + 11] + line4[xx * 4 + 15] +
|
||||||
|
line4[xx * 4 + 19];
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
|
((ss0 + amend) * multiplier) >> 24,
|
||||||
((ss2 + amend) * multiplier) >> 24, ((ss3 + amend) * multiplier) >> 24);
|
((ss1 + amend) * multiplier) >> 24,
|
||||||
|
((ss2 + amend) * multiplier) >> 24,
|
||||||
|
((ss3 + amend) * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1056,10 +1100,8 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale)
|
ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale) {
|
||||||
{
|
|
||||||
/* Fill the last row and the last column for any xscale and yscale.
|
/* Fill the last row and the last column for any xscale and yscale.
|
||||||
*/
|
*/
|
||||||
int x, y, xx, yy;
|
int x, y, xx, yy;
|
||||||
|
@ -1136,8 +1178,10 @@ ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int ys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, (ss3 * multiplier) >> 24);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
(ss3 * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1160,8 +1204,10 @@ ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int ys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, (ss3 * multiplier) >> 24);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
(ss3 * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1183,17 +1229,18 @@ ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int ys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(
|
v = MAKE_UINT32(
|
||||||
(ss0 * multiplier) >> 24, (ss1 * multiplier) >> 24,
|
(ss0 * multiplier) >> 24,
|
||||||
(ss2 * multiplier) >> 24, (ss3 * multiplier) >> 24);
|
(ss1 * multiplier) >> 24,
|
||||||
|
(ss2 * multiplier) >> 24,
|
||||||
|
(ss3 * multiplier) >> 24);
|
||||||
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduceNxN_32bpc(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale)
|
ImagingReduceNxN_32bpc(
|
||||||
{
|
Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale) {
|
||||||
/* The most general implementation for any xscale and yscale
|
/* The most general implementation for any xscale and yscale
|
||||||
*/
|
*/
|
||||||
int x, y, xx, yy;
|
int x, y, xx, yy;
|
||||||
|
@ -1210,8 +1257,8 @@ ImagingReduceNxN_32bpc(Imaging imOut, Imaging imIn, int box[4], int xscale, int
|
||||||
INT32 *line0 = (INT32 *)imIn->image32[yy];
|
INT32 *line0 = (INT32 *)imIn->image32[yy];
|
||||||
INT32 *line1 = (INT32 *)imIn->image32[yy + 1];
|
INT32 *line1 = (INT32 *)imIn->image32[yy + 1];
|
||||||
for (xx = xx_from; xx < xx_from + xscale - 1; xx += 2) {
|
for (xx = xx_from; xx < xx_from + xscale - 1; xx += 2) {
|
||||||
ss += line0[xx + 0] + line0[xx + 1] +
|
ss += line0[xx + 0] + line0[xx + 1] + line1[xx + 0] +
|
||||||
line1[xx + 0] + line1[xx + 1];
|
line1[xx + 1];
|
||||||
}
|
}
|
||||||
if (xscale & 0x01) {
|
if (xscale & 0x01) {
|
||||||
ss += line0[xx + 0] + line1[xx + 0];
|
ss += line0[xx + 0] + line1[xx + 0];
|
||||||
|
@ -1241,8 +1288,8 @@ ImagingReduceNxN_32bpc(Imaging imOut, Imaging imIn, int box[4], int xscale, int
|
||||||
FLOAT32 *line0 = (FLOAT32 *)imIn->image32[yy];
|
FLOAT32 *line0 = (FLOAT32 *)imIn->image32[yy];
|
||||||
FLOAT32 *line1 = (FLOAT32 *)imIn->image32[yy + 1];
|
FLOAT32 *line1 = (FLOAT32 *)imIn->image32[yy + 1];
|
||||||
for (xx = xx_from; xx < xx_from + xscale - 1; xx += 2) {
|
for (xx = xx_from; xx < xx_from + xscale - 1; xx += 2) {
|
||||||
ss += line0[xx + 0] + line0[xx + 1] +
|
ss += line0[xx + 0] + line0[xx + 1] + line1[xx + 0] +
|
||||||
line1[xx + 0] + line1[xx + 1];
|
line1[xx + 1];
|
||||||
}
|
}
|
||||||
if (xscale & 0x01) {
|
if (xscale & 0x01) {
|
||||||
ss += line0[xx + 0] + line1[xx + 0];
|
ss += line0[xx + 0] + line1[xx + 0];
|
||||||
|
@ -1264,10 +1311,9 @@ ImagingReduceNxN_32bpc(Imaging imOut, Imaging imIn, int box[4], int xscale, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingReduceCorners_32bpc(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale)
|
ImagingReduceCorners_32bpc(
|
||||||
{
|
Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale) {
|
||||||
/* Fill the last row and the last column for any xscale and yscale.
|
/* Fill the last row and the last column for any xscale and yscale.
|
||||||
*/
|
*/
|
||||||
int x, y, xx, yy;
|
int x, y, xx, yy;
|
||||||
|
@ -1367,10 +1413,8 @@ ImagingReduceCorners_32bpc(Imaging imOut, Imaging imIn, int box[4], int xscale,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4])
|
ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
Imaging imOut = NULL;
|
Imaging imOut = NULL;
|
||||||
|
|
||||||
|
@ -1382,9 +1426,8 @@ ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4])
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
imOut = ImagingNewDirty(imIn->mode,
|
imOut = ImagingNewDirty(
|
||||||
(box[2] + xscale - 1) / xscale,
|
imIn->mode, (box[2] + xscale - 1) / xscale, (box[3] + yscale - 1) / yscale);
|
||||||
(box[3] + yscale - 1) / yscale);
|
|
||||||
if (!imOut) {
|
if (!imOut) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,23 @@
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
#define ROUND_UP(f) ((int)((f) >= 0.0 ? (f) + 0.5F : (f)-0.5F))
|
#define ROUND_UP(f) ((int)((f) >= 0.0 ? (f) + 0.5F : (f)-0.5F))
|
||||||
|
|
||||||
|
|
||||||
struct filter {
|
struct filter {
|
||||||
double (*filter)(double x);
|
double (*filter)(double x);
|
||||||
double support;
|
double support;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline double box_filter(double x)
|
static inline double
|
||||||
{
|
box_filter(double x) {
|
||||||
if (x > -0.5 && x <= 0.5) {
|
if (x > -0.5 && x <= 0.5) {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double bilinear_filter(double x)
|
static inline double
|
||||||
{
|
bilinear_filter(double x) {
|
||||||
if (x < 0.0) {
|
if (x < 0.0) {
|
||||||
x = -x;
|
x = -x;
|
||||||
}
|
}
|
||||||
|
@ -30,8 +28,8 @@ static inline double bilinear_filter(double x)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double hamming_filter(double x)
|
static inline double
|
||||||
{
|
hamming_filter(double x) {
|
||||||
if (x < 0.0) {
|
if (x < 0.0) {
|
||||||
x = -x;
|
x = -x;
|
||||||
}
|
}
|
||||||
|
@ -45,9 +43,10 @@ static inline double hamming_filter(double x)
|
||||||
return sin(x) / x * (0.54f + 0.46f * cos(x));
|
return sin(x) / x * (0.54f + 0.46f * cos(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double bicubic_filter(double x)
|
static inline double
|
||||||
{
|
bicubic_filter(double x) {
|
||||||
/* https://en.wikipedia.org/wiki/Bicubic_interpolation#Bicubic_convolution_algorithm */
|
/* https://en.wikipedia.org/wiki/Bicubic_interpolation#Bicubic_convolution_algorithm
|
||||||
|
*/
|
||||||
#define a -0.5
|
#define a -0.5
|
||||||
if (x < 0.0) {
|
if (x < 0.0) {
|
||||||
x = -x;
|
x = -x;
|
||||||
|
@ -62,8 +61,8 @@ static inline double bicubic_filter(double x)
|
||||||
#undef a
|
#undef a
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double sinc_filter(double x)
|
static inline double
|
||||||
{
|
sinc_filter(double x) {
|
||||||
if (x == 0.0) {
|
if (x == 0.0) {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
@ -71,8 +70,8 @@ static inline double sinc_filter(double x)
|
||||||
return sin(x) / x;
|
return sin(x) / x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double lanczos_filter(double x)
|
static inline double
|
||||||
{
|
lanczos_filter(double x) {
|
||||||
/* truncated sinc */
|
/* truncated sinc */
|
||||||
if (-3.0 <= x && x < 3.0) {
|
if (-3.0 <= x && x < 3.0) {
|
||||||
return sinc_filter(x) * sinc_filter(x / 3);
|
return sinc_filter(x) * sinc_filter(x / 3);
|
||||||
|
@ -86,109 +85,108 @@ static struct filter HAMMING = { hamming_filter, 1.0 };
|
||||||
static struct filter BICUBIC = {bicubic_filter, 2.0};
|
static struct filter BICUBIC = {bicubic_filter, 2.0};
|
||||||
static struct filter LANCZOS = {lanczos_filter, 3.0};
|
static struct filter LANCZOS = {lanczos_filter, 3.0};
|
||||||
|
|
||||||
|
|
||||||
/* 8 bits for result. Filter can have negative areas.
|
/* 8 bits for result. Filter can have negative areas.
|
||||||
In one cases the sum of the coefficients will be negative,
|
In one cases the sum of the coefficients will be negative,
|
||||||
in the other it will be more than 1.0. That is why we need
|
in the other it will be more than 1.0. That is why we need
|
||||||
two extra bits for overflow and int type. */
|
two extra bits for overflow and int type. */
|
||||||
#define PRECISION_BITS (32 - 8 - 2)
|
#define PRECISION_BITS (32 - 8 - 2)
|
||||||
|
|
||||||
|
|
||||||
/* Handles values form -640 to 639. */
|
/* Handles values form -640 to 639. */
|
||||||
UINT8 _clip8_lookups[1280] = {
|
UINT8 _clip8_lookups[1280] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
|
||||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
|
||||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
|
||||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
|
||||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
|
||||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
|
||||||
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
|
||||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
|
159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
|
||||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
|
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
|
||||||
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
|
||||||
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
|
210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
|
||||||
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
|
227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243,
|
||||||
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
|
244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255, 255, 255, 255, 255,
|
||||||
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 255,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
UINT8 *clip8_lookups = &_clip8_lookups[640];
|
UINT8 *clip8_lookups = &_clip8_lookups[640];
|
||||||
|
|
||||||
static inline UINT8 clip8(int in)
|
static inline UINT8
|
||||||
{
|
clip8(int in) {
|
||||||
return clip8_lookups[in >> PRECISION_BITS];
|
return clip8_lookups[in >> PRECISION_BITS];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
precompute_coeffs(int inSize, float in0, float in1, int outSize,
|
precompute_coeffs(
|
||||||
struct filter *filterp, int **boundsp, double **kkp) {
|
int inSize,
|
||||||
|
float in0,
|
||||||
|
float in1,
|
||||||
|
int outSize,
|
||||||
|
struct filter *filterp,
|
||||||
|
int **boundsp,
|
||||||
|
double **kkp) {
|
||||||
double support, scale, filterscale;
|
double support, scale, filterscale;
|
||||||
double center, ww, ss;
|
double center, ww, ss;
|
||||||
int xx, x, ksize, xmin, xmax;
|
int xx, x, ksize, xmin, xmax;
|
||||||
|
@ -267,10 +265,8 @@ precompute_coeffs(int inSize, float in0, float in1, int outSize,
|
||||||
return ksize;
|
return ksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
normalize_coeffs_8bpc(int outSize, int ksize, double *prekk)
|
normalize_coeffs_8bpc(int outSize, int ksize, double *prekk) {
|
||||||
{
|
|
||||||
int x;
|
int x;
|
||||||
INT32 *kk;
|
INT32 *kk;
|
||||||
|
|
||||||
|
@ -286,12 +282,9 @@ normalize_coeffs_8bpc(int outSize, int ksize, double *prekk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset,
|
ImagingResampleHorizontal_8bpc(
|
||||||
int ksize, int *bounds, double *prekk)
|
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *prekk) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int ss0, ss1, ss2, ss3;
|
int ss0, ss1, ss2, ss3;
|
||||||
int xx, yy, x, xmin, xmax;
|
int xx, yy, x, xmin, xmax;
|
||||||
|
@ -325,8 +318,10 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset,
|
||||||
k = &kk[xx * ksize];
|
k = &kk[xx * ksize];
|
||||||
ss0 = ss3 = 1 << (PRECISION_BITS - 1);
|
ss0 = ss3 = 1 << (PRECISION_BITS - 1);
|
||||||
for (x = 0; x < xmax; x++) {
|
for (x = 0; x < xmax; x++) {
|
||||||
ss0 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 0]) * k[x];
|
ss0 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 0]) *
|
||||||
ss3 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 3]) * k[x];
|
k[x];
|
||||||
|
ss3 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 3]) *
|
||||||
|
k[x];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3));
|
v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3));
|
||||||
memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
|
||||||
|
@ -341,9 +336,12 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset,
|
||||||
k = &kk[xx * ksize];
|
k = &kk[xx * ksize];
|
||||||
ss0 = ss1 = ss2 = 1 << (PRECISION_BITS - 1);
|
ss0 = ss1 = ss2 = 1 << (PRECISION_BITS - 1);
|
||||||
for (x = 0; x < xmax; x++) {
|
for (x = 0; x < xmax; x++) {
|
||||||
ss0 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 0]) * k[x];
|
ss0 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 0]) *
|
||||||
ss1 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 1]) * k[x];
|
k[x];
|
||||||
ss2 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 2]) * k[x];
|
ss1 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 1]) *
|
||||||
|
k[x];
|
||||||
|
ss2 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 2]) *
|
||||||
|
k[x];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0);
|
v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0);
|
||||||
memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
|
||||||
|
@ -358,10 +356,14 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset,
|
||||||
k = &kk[xx * ksize];
|
k = &kk[xx * ksize];
|
||||||
ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS - 1);
|
ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS - 1);
|
||||||
for (x = 0; x < xmax; x++) {
|
for (x = 0; x < xmax; x++) {
|
||||||
ss0 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 0]) * k[x];
|
ss0 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 0]) *
|
||||||
ss1 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 1]) * k[x];
|
k[x];
|
||||||
ss2 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 2]) * k[x];
|
ss1 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 1]) *
|
||||||
ss3 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 3]) * k[x];
|
k[x];
|
||||||
|
ss2 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 2]) *
|
||||||
|
k[x];
|
||||||
|
ss3 += ((UINT8)imIn->image[yy + offset][(x + xmin) * 4 + 3]) *
|
||||||
|
k[x];
|
||||||
}
|
}
|
||||||
v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3));
|
v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3));
|
||||||
memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
|
memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v));
|
||||||
|
@ -372,11 +374,9 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset,
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset,
|
ImagingResampleVertical_8bpc(
|
||||||
int ksize, int *bounds, double *prekk)
|
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *prekk) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
int ss0, ss1, ss2, ss3;
|
int ss0, ss1, ss2, ss3;
|
||||||
int xx, yy, y, ymin, ymax;
|
int xx, yy, y, ymin, ymax;
|
||||||
|
@ -457,11 +457,9 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset,
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn, int offset,
|
ImagingResampleHorizontal_32bpc(
|
||||||
int ksize, int *bounds, double *kk)
|
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
double ss;
|
double ss;
|
||||||
int xx, yy, x, xmin, xmax;
|
int xx, yy, x, xmin, xmax;
|
||||||
|
@ -502,11 +500,9 @@ ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn, int offset,
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn, int offset,
|
ImagingResampleVertical_32bpc(
|
||||||
int ksize, int *bounds, double *kk)
|
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
double ss;
|
double ss;
|
||||||
int xx, yy, y, ymin, ymax;
|
int xx, yy, y, ymin, ymax;
|
||||||
|
@ -547,21 +543,21 @@ ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn, int offset,
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void (*ResampleFunction)(
|
||||||
typedef void (*ResampleFunction)(Imaging imOut, Imaging imIn, int offset,
|
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk);
|
||||||
int ksize, int *bounds, double *kk);
|
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
ImagingResampleInner(
|
||||||
struct filter *filterp, float box[4],
|
Imaging imIn,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
struct filter *filterp,
|
||||||
|
float box[4],
|
||||||
ResampleFunction ResampleHorizontal,
|
ResampleFunction ResampleHorizontal,
|
||||||
ResampleFunction ResampleVertical);
|
ResampleFunction ResampleVertical);
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4])
|
ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) {
|
||||||
{
|
|
||||||
struct filter *filterp;
|
struct filter *filterp;
|
||||||
ResampleFunction ResampleHorizontal;
|
ResampleFunction ResampleHorizontal;
|
||||||
ResampleFunction ResampleVertical;
|
ResampleFunction ResampleVertical;
|
||||||
|
@ -609,22 +605,22 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4])
|
||||||
filterp = &LANCZOS;
|
filterp = &LANCZOS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (Imaging) ImagingError_ValueError(
|
return (Imaging)ImagingError_ValueError("unsupported resampling filter");
|
||||||
"unsupported resampling filter"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImagingResampleInner(imIn, xsize, ysize, filterp, box,
|
return ImagingResampleInner(
|
||||||
ResampleHorizontal, ResampleVertical);
|
imIn, xsize, ysize, filterp, box, ResampleHorizontal, ResampleVertical);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
ImagingResampleInner(
|
||||||
struct filter *filterp, float box[4],
|
Imaging imIn,
|
||||||
|
int xsize,
|
||||||
|
int ysize,
|
||||||
|
struct filter *filterp,
|
||||||
|
float box[4],
|
||||||
ResampleFunction ResampleHorizontal,
|
ResampleFunction ResampleHorizontal,
|
||||||
ResampleFunction ResampleVertical)
|
ResampleFunction ResampleVertical) {
|
||||||
{
|
|
||||||
Imaging imTemp = NULL;
|
Imaging imTemp = NULL;
|
||||||
Imaging imOut = NULL;
|
Imaging imOut = NULL;
|
||||||
|
|
||||||
|
@ -637,14 +633,14 @@ ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
||||||
need_horizontal = xsize != imIn->xsize || box[0] || box[2] != xsize;
|
need_horizontal = xsize != imIn->xsize || box[0] || box[2] != xsize;
|
||||||
need_vertical = ysize != imIn->ysize || box[1] || box[3] != ysize;
|
need_vertical = ysize != imIn->ysize || box[1] || box[3] != ysize;
|
||||||
|
|
||||||
ksize_horiz = precompute_coeffs(imIn->xsize, box[0], box[2], xsize,
|
ksize_horiz = precompute_coeffs(
|
||||||
filterp, &bounds_horiz, &kk_horiz);
|
imIn->xsize, box[0], box[2], xsize, filterp, &bounds_horiz, &kk_horiz);
|
||||||
if (!ksize_horiz) {
|
if (!ksize_horiz) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ksize_vert = precompute_coeffs(imIn->ysize, box[1], box[3], ysize,
|
ksize_vert = precompute_coeffs(
|
||||||
filterp, &bounds_vert, &kk_vert);
|
imIn->ysize, box[1], box[3], ysize, filterp, &bounds_vert, &kk_vert);
|
||||||
if (!ksize_vert) {
|
if (!ksize_vert) {
|
||||||
free(bounds_horiz);
|
free(bounds_horiz);
|
||||||
free(kk_horiz);
|
free(kk_horiz);
|
||||||
|
@ -656,7 +652,6 @@ ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
||||||
// Last used row in the source image
|
// Last used row in the source image
|
||||||
ybox_last = bounds_vert[ysize * 2 - 2] + bounds_vert[ysize * 2 - 1];
|
ybox_last = bounds_vert[ysize * 2 - 2] + bounds_vert[ysize * 2 - 1];
|
||||||
|
|
||||||
|
|
||||||
/* two-pass resize, horizontal pass */
|
/* two-pass resize, horizontal pass */
|
||||||
if (need_horizontal) {
|
if (need_horizontal) {
|
||||||
// Shift bounds for vertical pass
|
// Shift bounds for vertical pass
|
||||||
|
@ -666,8 +661,8 @@ ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
||||||
|
|
||||||
imTemp = ImagingNewDirty(imIn->mode, xsize, ybox_last - ybox_first);
|
imTemp = ImagingNewDirty(imIn->mode, xsize, ybox_last - ybox_first);
|
||||||
if (imTemp) {
|
if (imTemp) {
|
||||||
ResampleHorizontal(imTemp, imIn, ybox_first,
|
ResampleHorizontal(
|
||||||
ksize_horiz, bounds_horiz, kk_horiz);
|
imTemp, imIn, ybox_first, ksize_horiz, bounds_horiz, kk_horiz);
|
||||||
}
|
}
|
||||||
free(bounds_horiz);
|
free(bounds_horiz);
|
||||||
free(kk_horiz);
|
free(kk_horiz);
|
||||||
|
@ -688,8 +683,7 @@ ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
||||||
imOut = ImagingNewDirty(imIn->mode, imIn->xsize, ysize);
|
imOut = ImagingNewDirty(imIn->mode, imIn->xsize, ysize);
|
||||||
if (imOut) {
|
if (imOut) {
|
||||||
/* imIn can be the original image or horizontally resampled one */
|
/* imIn can be the original image or horizontally resampled one */
|
||||||
ResampleVertical(imOut, imIn, 0,
|
ResampleVertical(imOut, imIn, 0, ksize_vert, bounds_vert, kk_vert);
|
||||||
ksize_vert, bounds_vert, kk_vert);
|
|
||||||
}
|
}
|
||||||
/* it's safe to call ImagingDelete with empty value
|
/* it's safe to call ImagingDelete with empty value
|
||||||
if previous step was not performed. */
|
if previous step was not performed. */
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* Sgi.h */
|
/* Sgi.h */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* CONFIGURATION */
|
/* CONFIGURATION */
|
||||||
|
|
||||||
/* Number of bytes per channel per pixel */
|
/* Number of bytes per channel per pixel */
|
||||||
|
|
|
@ -20,18 +20,17 @@
|
||||||
#define RLE_COPY_FLAG 0x80
|
#define RLE_COPY_FLAG 0x80
|
||||||
#define RLE_MAX_RUN 0x7f
|
#define RLE_MAX_RUN 0x7f
|
||||||
|
|
||||||
static void read4B(UINT32* dest, UINT8* buf)
|
static void
|
||||||
{
|
read4B(UINT32 *dest, UINT8 *buf) {
|
||||||
*dest = (UINT32)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
|
*dest = (UINT32)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
|
static int
|
||||||
{
|
expandrow(UINT8 *dest, UINT8 *src, int n, int z, int xsize) {
|
||||||
UINT8 pixel, count;
|
UINT8 pixel, count;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
|
||||||
for (;n > 0; n--)
|
for (; n > 0; n--) {
|
||||||
{
|
|
||||||
pixel = *src++;
|
pixel = *src++;
|
||||||
if (n == 1 && pixel != 0) {
|
if (n == 1 && pixel != 0) {
|
||||||
return n;
|
return n;
|
||||||
|
@ -50,27 +49,24 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
|
||||||
dest += z;
|
dest += z;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
pixel = *src++;
|
pixel = *src++;
|
||||||
while (count--) {
|
while (count--) {
|
||||||
*dest = pixel;
|
*dest = pixel;
|
||||||
dest += z;
|
dest += z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
|
static int
|
||||||
{
|
expandrow2(UINT8 *dest, const UINT8 *src, int n, int z, int xsize) {
|
||||||
UINT8 pixel, count;
|
UINT8 pixel, count;
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
|
||||||
for (;n > 0; n--)
|
for (; n > 0; n--) {
|
||||||
{
|
|
||||||
pixel = src[1];
|
pixel = src[1];
|
||||||
src += 2;
|
src += 2;
|
||||||
if (n == 1 && pixel != 0) {
|
if (n == 1 && pixel != 0) {
|
||||||
|
@ -90,8 +86,7 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
|
||||||
src += 2;
|
src += 2;
|
||||||
dest += z * 2;
|
dest += z * 2;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
memcpy(dest, src, 2);
|
memcpy(dest, src, 2);
|
||||||
dest += z * 2;
|
dest += z * 2;
|
||||||
|
@ -102,19 +97,15 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
ImagingSgiRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
UINT8* buf, Py_ssize_t bytes)
|
|
||||||
{
|
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
SGISTATE *c;
|
SGISTATE *c;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
/* size check */
|
/* size check */
|
||||||
if (im->xsize > INT_MAX / im->bands ||
|
if (im->xsize > INT_MAX / im->bands || im->ysize > INT_MAX / im->bands) {
|
||||||
im->ysize > INT_MAX / im->bands) {
|
|
||||||
state->errcode = IMAGING_CODEC_MEMORY;
|
state->errcode = IMAGING_CODEC_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +134,6 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
||||||
_imaging_seek_pyFd(state->fd, SGI_HEADER_SIZE, SEEK_SET);
|
_imaging_seek_pyFd(state->fd, SGI_HEADER_SIZE, SEEK_SET);
|
||||||
_imaging_read_pyFd(state->fd, (char *)ptr, c->bufsize);
|
_imaging_read_pyFd(state->fd, (char *)ptr, c->bufsize);
|
||||||
|
|
||||||
|
|
||||||
/* decoder initialization */
|
/* decoder initialization */
|
||||||
state->count = 0;
|
state->count = 0;
|
||||||
state->y = 0;
|
state->y = 0;
|
||||||
|
@ -160,28 +150,27 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
||||||
state->buffer = calloc(im->xsize * im->bands, sizeof(UINT8) * 2);
|
state->buffer = calloc(im->xsize * im->bands, sizeof(UINT8) * 2);
|
||||||
c->starttab = calloc(c->tablen, sizeof(UINT32));
|
c->starttab = calloc(c->tablen, sizeof(UINT32));
|
||||||
c->lengthtab = calloc(c->tablen, sizeof(UINT32));
|
c->lengthtab = calloc(c->tablen, sizeof(UINT32));
|
||||||
if (!state->buffer ||
|
if (!state->buffer || !c->starttab || !c->lengthtab) {
|
||||||
!c->starttab ||
|
|
||||||
!c->lengthtab) {
|
|
||||||
err = IMAGING_CODEC_MEMORY;
|
err = IMAGING_CODEC_MEMORY;
|
||||||
goto sgi_finish_decode;
|
goto sgi_finish_decode;
|
||||||
}
|
}
|
||||||
/* populate offsets table */
|
/* populate offsets table */
|
||||||
for (c->tabindex = 0, c->bufindex = 0; c->tabindex < c->tablen; c->tabindex++, c->bufindex+=4) {
|
for (c->tabindex = 0, c->bufindex = 0; c->tabindex < c->tablen;
|
||||||
|
c->tabindex++, c->bufindex += 4) {
|
||||||
read4B(&c->starttab[c->tabindex], &ptr[c->bufindex]);
|
read4B(&c->starttab[c->tabindex], &ptr[c->bufindex]);
|
||||||
}
|
}
|
||||||
/* populate lengths table */
|
/* populate lengths table */
|
||||||
for (c->tabindex = 0, c->bufindex = c->tablen * sizeof(UINT32); c->tabindex < c->tablen; c->tabindex++, c->bufindex+=4) {
|
for (c->tabindex = 0, c->bufindex = c->tablen * sizeof(UINT32);
|
||||||
|
c->tabindex < c->tablen;
|
||||||
|
c->tabindex++, c->bufindex += 4) {
|
||||||
read4B(&c->lengthtab[c->tabindex], &ptr[c->bufindex]);
|
read4B(&c->lengthtab[c->tabindex], &ptr[c->bufindex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
state->count += c->tablen * sizeof(UINT32) * 2;
|
state->count += c->tablen * sizeof(UINT32) * 2;
|
||||||
|
|
||||||
/* read compressed rows */
|
/* read compressed rows */
|
||||||
for (c->rowno = 0; c->rowno < im->ysize; c->rowno++, state->y += state->ystep)
|
for (c->rowno = 0; c->rowno < im->ysize; c->rowno++, state->y += state->ystep) {
|
||||||
{
|
for (c->channo = 0; c->channo < im->bands; c->channo++) {
|
||||||
for (c->channo = 0; c->channo < im->bands; c->channo++)
|
|
||||||
{
|
|
||||||
c->rleoffset = c->starttab[c->rowno + c->channo * im->ysize];
|
c->rleoffset = c->starttab[c->rowno + c->channo * im->ysize];
|
||||||
c->rlelength = c->lengthtab[c->rowno + c->channo * im->ysize];
|
c->rlelength = c->lengthtab[c->rowno + c->channo * im->ysize];
|
||||||
c->rleoffset -= SGI_HEADER_SIZE;
|
c->rleoffset -= SGI_HEADER_SIZE;
|
||||||
|
@ -193,10 +182,19 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
||||||
|
|
||||||
/* row decompression */
|
/* row decompression */
|
||||||
if (c->bpc == 1) {
|
if (c->bpc == 1) {
|
||||||
status = expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize);
|
status = expandrow(
|
||||||
}
|
&state->buffer[c->channo],
|
||||||
else {
|
&ptr[c->rleoffset],
|
||||||
status = expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize);
|
c->rlelength,
|
||||||
|
im->bands,
|
||||||
|
im->xsize);
|
||||||
|
} else {
|
||||||
|
status = expandrow2(
|
||||||
|
&state->buffer[c->channo * 2],
|
||||||
|
&ptr[c->rleoffset],
|
||||||
|
c->rlelength,
|
||||||
|
im->bands,
|
||||||
|
im->xsize);
|
||||||
}
|
}
|
||||||
if (status == -1) {
|
if (status == -1) {
|
||||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
state->errcode = IMAGING_CODEC_OVERRUN;
|
||||||
|
@ -210,7 +208,6 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
||||||
|
|
||||||
/* store decompressed data in image */
|
/* store decompressed data in image */
|
||||||
state->shuffle((UINT8 *)im->image[state->y], state->buffer, im->xsize);
|
state->shuffle((UINT8 *)im->image[state->y], state->buffer, im->xsize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c->bufsize++;
|
c->bufsize++;
|
||||||
|
|
|
@ -34,11 +34,9 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
int ImagingNewCount = 0;
|
int ImagingNewCount = 0;
|
||||||
|
|
||||||
/* --------------------------------------------------------------------
|
/* --------------------------------------------------------------------
|
||||||
|
@ -46,8 +44,7 @@ int ImagingNewCount = 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size)
|
ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
|
||||||
{
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
|
||||||
/* linesize overflow check, roughly the current largest space req'd */
|
/* linesize overflow check, roughly the current largest space req'd */
|
||||||
|
@ -115,8 +112,9 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size)
|
||||||
im->linesize = xsize * 4;
|
im->linesize = xsize * 4;
|
||||||
im->type = IMAGING_TYPE_INT32;
|
im->type = IMAGING_TYPE_INT32;
|
||||||
|
|
||||||
} else if (strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 \
|
} else if (
|
||||||
|| strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0) {
|
strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 ||
|
||||||
|
strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0) {
|
||||||
/* EXPERIMENTAL */
|
/* EXPERIMENTAL */
|
||||||
/* 16-bit raw integer images */
|
/* 16-bit raw integer images */
|
||||||
im->bands = 1;
|
im->bands = 1;
|
||||||
|
@ -221,7 +219,9 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size)
|
||||||
|
|
||||||
/* Initialize alias pointers to pixel data. */
|
/* Initialize alias pointers to pixel data. */
|
||||||
switch (im->pixelsize) {
|
switch (im->pixelsize) {
|
||||||
case 1: case 2: case 3:
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
im->image8 = (UINT8 **)im->image;
|
im->image8 = (UINT8 **)im->image;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -235,15 +235,13 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNewPrologue(const char *mode, int xsize, int ysize)
|
ImagingNewPrologue(const char *mode, int xsize, int ysize) {
|
||||||
{
|
|
||||||
return ImagingNewPrologueSubtype(
|
return ImagingNewPrologueSubtype(
|
||||||
mode, xsize, ysize, sizeof(struct ImagingMemoryInstance));
|
mode, xsize, ysize, sizeof(struct ImagingMemoryInstance));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingDelete(Imaging im)
|
ImagingDelete(Imaging im) {
|
||||||
{
|
|
||||||
if (!im) {
|
if (!im) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +261,6 @@ ImagingDelete(Imaging im)
|
||||||
free(im);
|
free(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Array Storage Type */
|
/* Array Storage Type */
|
||||||
/* ------------------ */
|
/* ------------------ */
|
||||||
/* Allocate image as an array of line buffers. */
|
/* Allocate image as an array of line buffers. */
|
||||||
|
@ -276,12 +273,15 @@ struct ImagingMemoryArena ImagingDefaultArena = {
|
||||||
0, // blocks_max
|
0, // blocks_max
|
||||||
0, // blocks_cached
|
0, // blocks_cached
|
||||||
NULL, // blocks_pool
|
NULL, // blocks_pool
|
||||||
0, 0, 0, 0, 0 // Stats
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0 // Stats
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingMemorySetBlocksMax(ImagingMemoryArena arena, int blocks_max)
|
ImagingMemorySetBlocksMax(ImagingMemoryArena arena, int blocks_max) {
|
||||||
{
|
|
||||||
void *p;
|
void *p;
|
||||||
/* Free already cached blocks */
|
/* Free already cached blocks */
|
||||||
ImagingMemoryClearCache(arena, blocks_max);
|
ImagingMemoryClearCache(arena, blocks_max);
|
||||||
|
@ -308,8 +308,7 @@ ImagingMemorySetBlocksMax(ImagingMemoryArena arena, int blocks_max)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size)
|
ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size) {
|
||||||
{
|
|
||||||
while (arena->blocks_cached > new_size) {
|
while (arena->blocks_cached > new_size) {
|
||||||
arena->blocks_cached -= 1;
|
arena->blocks_cached -= 1;
|
||||||
free(arena->blocks_pool[arena->blocks_cached].ptr);
|
free(arena->blocks_pool[arena->blocks_cached].ptr);
|
||||||
|
@ -318,8 +317,7 @@ ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingMemoryBlock
|
ImagingMemoryBlock
|
||||||
memory_get_block(ImagingMemoryArena arena, int requested_size, int dirty)
|
memory_get_block(ImagingMemoryArena arena, int requested_size, int dirty) {
|
||||||
{
|
|
||||||
ImagingMemoryBlock block = {NULL, 0};
|
ImagingMemoryBlock block = {NULL, 0};
|
||||||
|
|
||||||
if (arena->blocks_cached > 0) {
|
if (arena->blocks_cached > 0) {
|
||||||
|
@ -356,8 +354,7 @@ memory_get_block(ImagingMemoryArena arena, int requested_size, int dirty)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
memory_return_block(ImagingMemoryArena arena, ImagingMemoryBlock block)
|
memory_return_block(ImagingMemoryArena arena, ImagingMemoryBlock block) {
|
||||||
{
|
|
||||||
if (arena->blocks_cached < arena->blocks_max) {
|
if (arena->blocks_cached < arena->blocks_max) {
|
||||||
// Reduce block size
|
// Reduce block size
|
||||||
if (block.size > arena->block_size) {
|
if (block.size > arena->block_size) {
|
||||||
|
@ -372,10 +369,8 @@ memory_return_block(ImagingMemoryArena arena, ImagingMemoryBlock block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ImagingDestroyArray(Imaging im)
|
ImagingDestroyArray(Imaging im) {
|
||||||
{
|
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
if (im->blocks) {
|
if (im->blocks) {
|
||||||
|
@ -388,8 +383,7 @@ ImagingDestroyArray(Imaging im)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingAllocateArray(Imaging im, int dirty, int block_size)
|
ImagingAllocateArray(Imaging im, int dirty, int block_size) {
|
||||||
{
|
|
||||||
int y, line_in_block, current_block;
|
int y, line_in_block, current_block;
|
||||||
ImagingMemoryArena arena = &ImagingDefaultArena;
|
ImagingMemoryArena arena = &ImagingDefaultArena;
|
||||||
ImagingMemoryBlock block = {NULL, 0};
|
ImagingMemoryBlock block = {NULL, 0};
|
||||||
|
@ -454,27 +448,23 @@ ImagingAllocateArray(Imaging im, int dirty, int block_size)
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Block Storage Type */
|
/* Block Storage Type */
|
||||||
/* ------------------ */
|
/* ------------------ */
|
||||||
/* Allocate image as a single block. */
|
/* Allocate image as a single block. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ImagingDestroyBlock(Imaging im)
|
ImagingDestroyBlock(Imaging im) {
|
||||||
{
|
|
||||||
if (im->block) {
|
if (im->block) {
|
||||||
free(im->block);
|
free(im->block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingAllocateBlock(Imaging im)
|
ImagingAllocateBlock(Imaging im) {
|
||||||
{
|
|
||||||
Py_ssize_t y, i;
|
Py_ssize_t y, i;
|
||||||
|
|
||||||
/* overflow check for malloc */
|
/* overflow check for malloc */
|
||||||
if (im->linesize &&
|
if (im->linesize && im->ysize > INT_MAX / im->linesize) {
|
||||||
im->ysize > INT_MAX / im->linesize) {
|
|
||||||
return (Imaging)ImagingError_MemoryError();
|
return (Imaging)ImagingError_MemoryError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,8 +497,7 @@ ImagingAllocateBlock(Imaging im)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNewInternal(const char* mode, int xsize, int ysize, int dirty)
|
ImagingNewInternal(const char *mode, int xsize, int ysize, int dirty) {
|
||||||
{
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
|
||||||
if (xsize < 0 || ysize < 0) {
|
if (xsize < 0 || ysize < 0) {
|
||||||
|
@ -536,20 +525,17 @@ ImagingNewInternal(const char* mode, int xsize, int ysize, int dirty)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNew(const char* mode, int xsize, int ysize)
|
ImagingNew(const char *mode, int xsize, int ysize) {
|
||||||
{
|
|
||||||
return ImagingNewInternal(mode, xsize, ysize, 0);
|
return ImagingNewInternal(mode, xsize, ysize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNewDirty(const char* mode, int xsize, int ysize)
|
ImagingNewDirty(const char *mode, int xsize, int ysize) {
|
||||||
{
|
|
||||||
return ImagingNewInternal(mode, xsize, ysize, 1);
|
return ImagingNewInternal(mode, xsize, ysize, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNewBlock(const char* mode, int xsize, int ysize)
|
ImagingNewBlock(const char *mode, int xsize, int ysize) {
|
||||||
{
|
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
|
||||||
if (xsize < 0 || ysize < 0) {
|
if (xsize < 0 || ysize < 0) {
|
||||||
|
@ -570,15 +556,13 @@ ImagingNewBlock(const char* mode, int xsize, int ysize)
|
||||||
}
|
}
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingNew2Dirty(const char* mode, Imaging imOut, Imaging imIn)
|
ImagingNew2Dirty(const char *mode, Imaging imOut, Imaging imIn) {
|
||||||
{
|
|
||||||
/* allocate or validate output image */
|
/* allocate or validate output image */
|
||||||
|
|
||||||
if (imOut) {
|
if (imOut) {
|
||||||
/* make sure images match */
|
/* make sure images match */
|
||||||
if (strcmp(imOut->mode, mode) != 0
|
if (strcmp(imOut->mode, mode) != 0 || imOut->xsize != imIn->xsize ||
|
||||||
|| imOut->xsize != imIn->xsize
|
imOut->ysize != imIn->ysize) {
|
||||||
|| imOut->ysize != imIn->ysize) {
|
|
||||||
return ImagingError_Mismatch();
|
return ImagingError_Mismatch();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -593,8 +577,7 @@ ImagingNew2Dirty(const char* mode, Imaging imOut, Imaging imIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingCopyPalette(Imaging destination, Imaging source)
|
ImagingCopyPalette(Imaging destination, Imaging source) {
|
||||||
{
|
|
||||||
if (source->palette) {
|
if (source->palette) {
|
||||||
if (destination->palette) {
|
if (destination->palette) {
|
||||||
ImagingPaletteDelete(destination->palette);
|
ImagingPaletteDelete(destination->palette);
|
||||||
|
|
|
@ -15,13 +15,10 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
int n;
|
int n;
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
UINT8 extra_data = 0;
|
UINT8 extra_data = 0;
|
||||||
|
@ -30,22 +27,18 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (bytes < 1) {
|
if (bytes < 1) {
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr[0] == 0x80) {
|
if (ptr[0] == 0x80) {
|
||||||
|
|
||||||
if (bytes < 2) {
|
if (bytes < 2) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = ptr[1];
|
n = ptr[1];
|
||||||
|
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
|
||||||
/* Literal 0x80 (2 bytes) */
|
/* Literal 0x80 (2 bytes) */
|
||||||
n = 1;
|
n = 1;
|
||||||
|
|
||||||
|
@ -55,7 +48,6 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t
|
||||||
bytes -= 2;
|
bytes -= 2;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Run (3 bytes) */
|
/* Run (3 bytes) */
|
||||||
if (bytes < 3) {
|
if (bytes < 3) {
|
||||||
break;
|
break;
|
||||||
|
@ -94,11 +86,9 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t
|
||||||
|
|
||||||
ptr += 3;
|
ptr += 3;
|
||||||
bytes -= 3;
|
bytes -= 3;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Literal byte */
|
/* Literal byte */
|
||||||
n = 1;
|
n = 1;
|
||||||
|
|
||||||
|
@ -106,17 +96,17 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t
|
||||||
|
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
bytes -= 1;
|
bytes -= 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
state->x += n;
|
state->x += n;
|
||||||
|
|
||||||
if (state->x >= state->bytes) {
|
if (state->x >= state->bytes) {
|
||||||
|
|
||||||
/* Got a full line, unpack it */
|
/* Got a full line, unpack it */
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
state->shuffle(
|
||||||
state->xoff * im->pixelsize, state->buffer,
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
|
state->xoff * im->pixelsize,
|
||||||
|
state->buffer,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
|
||||||
state->x = 0;
|
state->x = 0;
|
||||||
|
|
|
@ -14,21 +14,16 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
|
ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
UINT8* buf, Py_ssize_t bytes)
|
|
||||||
{
|
|
||||||
int n, depth;
|
int n, depth;
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
|
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
if (state->state == 0) {
|
if (state->state == 0) {
|
||||||
|
|
||||||
/* check image orientation */
|
/* check image orientation */
|
||||||
if (state->ystep < 0) {
|
if (state->ystep < 0) {
|
||||||
state->y = state->ysize - 1;
|
state->y = state->ysize - 1;
|
||||||
|
@ -38,19 +33,16 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
|
||||||
}
|
}
|
||||||
|
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
depth = state->count;
|
depth = state->count;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (bytes < 1) {
|
if (bytes < 1) {
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr[0] & 0x80) {
|
if (ptr[0] & 0x80) {
|
||||||
|
|
||||||
/* Run (1 + pixelsize bytes) */
|
/* Run (1 + pixelsize bytes) */
|
||||||
|
|
||||||
if (bytes < 1 + depth) {
|
if (bytes < 1 + depth) {
|
||||||
|
@ -77,7 +69,6 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
|
||||||
bytes -= 1 + depth;
|
bytes -= 1 + depth;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Literal (1+n+1 bytes block) */
|
/* Literal (1+n+1 bytes block) */
|
||||||
n = depth * (ptr[0] + 1);
|
n = depth * (ptr[0] + 1);
|
||||||
|
|
||||||
|
@ -94,16 +85,16 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
|
||||||
|
|
||||||
ptr += 1 + n;
|
ptr += 1 + n;
|
||||||
bytes -= 1 + n;
|
bytes -= 1 + n;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->x += n;
|
state->x += n;
|
||||||
|
|
||||||
if (state->x >= state->bytes) {
|
if (state->x >= state->bytes) {
|
||||||
|
|
||||||
/* Got a full line, unpack it */
|
/* Got a full line, unpack it */
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
state->shuffle(
|
||||||
state->xoff * im->pixelsize, state->buffer,
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
|
state->xoff * im->pixelsize,
|
||||||
|
state->buffer,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
|
||||||
state->x = 0;
|
state->x = 0;
|
||||||
|
@ -114,9 +105,7 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
|
||||||
/* End of file (errcode = 0) */
|
/* End of file (errcode = 0) */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
|
|
|
@ -4,17 +4,14 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
static int
|
||||||
static int comparePixels(const UINT8* buf, int x, int bytesPerPixel)
|
comparePixels(const UINT8 *buf, int x, int bytesPerPixel) {
|
||||||
{
|
|
||||||
buf += x * bytesPerPixel;
|
buf += x * bytesPerPixel;
|
||||||
return memcmp(buf, buf + bytesPerPixel, bytesPerPixel) == 0;
|
return memcmp(buf, buf + bytesPerPixel, bytesPerPixel) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
UINT8 *dst;
|
UINT8 *dst;
|
||||||
int bytesPerPixel;
|
int bytesPerPixel;
|
||||||
|
|
||||||
|
@ -64,8 +61,8 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
if (state->x == 0) {
|
if (state->x == 0) {
|
||||||
state->shuffle(
|
state->shuffle(
|
||||||
state->buffer,
|
state->buffer,
|
||||||
(UINT8*)im->image[state->y + state->yoff]
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
+ state->xoff * im->pixelsize,
|
state->xoff * im->pixelsize,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,9 +146,7 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(
|
memcpy(
|
||||||
dst,
|
dst, state->buffer + (state->x * bytesPerPixel - state->count), flushCount);
|
||||||
state->buffer + (state->x * bytesPerPixel - state->count),
|
|
||||||
flushCount);
|
|
||||||
dst += flushCount;
|
dst += flushCount;
|
||||||
bytes -= flushCount;
|
bytes -= flushCount;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
/* Convert C file descriptor to WinApi HFILE if LibTiff was compiled with tif_win32.c
|
/* Convert C file descriptor to WinApi HFILE if LibTiff was compiled with tif_win32.c
|
||||||
*
|
*
|
||||||
* This cast is safe, as the top 32-bits of HFILE are guaranteed to be zero,
|
* This cast is safe, as the top 32-bits of HFILE are guaranteed to be zero,
|
||||||
* see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
|
* see
|
||||||
|
* https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
|
||||||
*/
|
*/
|
||||||
#ifndef USE_WIN32_FILEIO
|
#ifndef USE_WIN32_FILEIO
|
||||||
#define fd_to_tiff_fd(fd) (fd)
|
#define fd_to_tiff_fd(fd) (fd)
|
||||||
|
@ -31,16 +32,23 @@
|
||||||
#define fd_to_tiff_fd(fd) ((int)_get_osfhandle(fd))
|
#define fd_to_tiff_fd(fd) ((int)_get_osfhandle(fd))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void dump_state(const TIFFSTATE *state){
|
void
|
||||||
TRACE(("State: Location %u size %d eof %d data: %p ifd: %d\n", (uint)state->loc,
|
dump_state(const TIFFSTATE *state) {
|
||||||
(int)state->size, (uint)state->eof, state->data, state->ifd));
|
TRACE(
|
||||||
|
("State: Location %u size %d eof %d data: %p ifd: %d\n",
|
||||||
|
(uint)state->loc,
|
||||||
|
(int)state->size,
|
||||||
|
(uint)state->eof,
|
||||||
|
state->data,
|
||||||
|
state->ifd));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
procs for TIFFOpenClient
|
procs for TIFFOpenClient
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tsize_t _tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) {
|
tsize_t
|
||||||
|
_tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) {
|
||||||
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
||||||
tsize_t to_read;
|
tsize_t to_read;
|
||||||
|
|
||||||
|
@ -57,7 +65,8 @@ tsize_t _tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) {
|
||||||
return to_read;
|
return to_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
tsize_t _tiffWriteProc(thandle_t hdata, tdata_t buf, tsize_t size) {
|
tsize_t
|
||||||
|
_tiffWriteProc(thandle_t hdata, tdata_t buf, tsize_t size) {
|
||||||
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
||||||
tsize_t to_write;
|
tsize_t to_write;
|
||||||
|
|
||||||
|
@ -97,7 +106,8 @@ tsize_t _tiffWriteProc(thandle_t hdata, tdata_t buf, tsize_t size) {
|
||||||
return to_write;
|
return to_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
toff_t _tiffSeekProc(thandle_t hdata, toff_t off, int whence) {
|
toff_t
|
||||||
|
_tiffSeekProc(thandle_t hdata, toff_t off, int whence) {
|
||||||
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
||||||
|
|
||||||
TRACE(("_tiffSeekProc: off: %u whence: %d \n", (uint)off, whence));
|
TRACE(("_tiffSeekProc: off: %u whence: %d \n", (uint)off, whence));
|
||||||
|
@ -117,7 +127,8 @@ toff_t _tiffSeekProc(thandle_t hdata, toff_t off, int whence) {
|
||||||
return state->loc;
|
return state->loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tiffCloseProc(thandle_t hdata) {
|
int
|
||||||
|
_tiffCloseProc(thandle_t hdata) {
|
||||||
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
||||||
|
|
||||||
TRACE(("_tiffCloseProc \n"));
|
TRACE(("_tiffCloseProc \n"));
|
||||||
|
@ -126,8 +137,8 @@ int _tiffCloseProc(thandle_t hdata) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toff_t
|
||||||
toff_t _tiffSizeProc(thandle_t hdata) {
|
_tiffSizeProc(thandle_t hdata) {
|
||||||
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
||||||
|
|
||||||
TRACE(("_tiffSizeProc \n"));
|
TRACE(("_tiffSizeProc \n"));
|
||||||
|
@ -136,7 +147,8 @@ toff_t _tiffSizeProc(thandle_t hdata) {
|
||||||
return (toff_t)state->size;
|
return (toff_t)state->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tiffMapProc(thandle_t hdata, tdata_t* pbase, toff_t* psize) {
|
int
|
||||||
|
_tiffMapProc(thandle_t hdata, tdata_t *pbase, toff_t *psize) {
|
||||||
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
TIFFSTATE *state = (TIFFSTATE *)hdata;
|
||||||
|
|
||||||
TRACE(("_tiffMapProc input size: %u, data: %p\n", (uint)*psize, *pbase));
|
TRACE(("_tiffMapProc input size: %u, data: %p\n", (uint)*psize, *pbase));
|
||||||
|
@ -148,25 +160,41 @@ int _tiffMapProc(thandle_t hdata, tdata_t* pbase, toff_t* psize) {
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tiffNullMapProc(thandle_t hdata, tdata_t* pbase, toff_t* psize) {
|
int
|
||||||
(void) hdata; (void) pbase; (void) psize;
|
_tiffNullMapProc(thandle_t hdata, tdata_t *pbase, toff_t *psize) {
|
||||||
|
(void)hdata;
|
||||||
|
(void)pbase;
|
||||||
|
(void)psize;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _tiffUnmapProc(thandle_t hdata, tdata_t base, toff_t size) {
|
void
|
||||||
|
_tiffUnmapProc(thandle_t hdata, tdata_t base, toff_t size) {
|
||||||
TRACE(("_tiffUnMapProc\n"));
|
TRACE(("_tiffUnMapProc\n"));
|
||||||
(void) hdata; (void) base; (void) size;
|
(void)hdata;
|
||||||
|
(void)base;
|
||||||
|
(void)size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImagingLibTiffInit(ImagingCodecState state, int fp, uint32 offset) {
|
int
|
||||||
|
ImagingLibTiffInit(ImagingCodecState state, int fp, uint32 offset) {
|
||||||
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
||||||
|
|
||||||
TRACE(("initing libtiff\n"));
|
TRACE(("initing libtiff\n"));
|
||||||
TRACE(("filepointer: %d \n", fp));
|
TRACE(("filepointer: %d \n", fp));
|
||||||
TRACE(("State: count %d, state %d, x %d, y %d, ystep %d\n", state->count, state->state,
|
TRACE(
|
||||||
state->x, state->y, state->ystep));
|
("State: count %d, state %d, x %d, y %d, ystep %d\n",
|
||||||
TRACE(("State: xsize %d, ysize %d, xoff %d, yoff %d \n", state->xsize, state->ysize,
|
state->count,
|
||||||
state->xoff, state->yoff));
|
state->state,
|
||||||
|
state->x,
|
||||||
|
state->y,
|
||||||
|
state->ystep));
|
||||||
|
TRACE(
|
||||||
|
("State: xsize %d, ysize %d, xoff %d, yoff %d \n",
|
||||||
|
state->xsize,
|
||||||
|
state->ysize,
|
||||||
|
state->xoff,
|
||||||
|
state->yoff));
|
||||||
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
|
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
|
||||||
TRACE(("State: context %p \n", state->context));
|
TRACE(("State: context %p \n", state->context));
|
||||||
|
|
||||||
|
@ -180,8 +208,8 @@ int ImagingLibTiffInit(ImagingCodecState state, int fp, uint32 offset) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
_decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
// To avoid dealing with YCbCr subsampling, let libtiff handle it
|
// To avoid dealing with YCbCr subsampling, let libtiff handle it
|
||||||
// Use a TIFFRGBAImage wrapping the tiff image, and let libtiff handle
|
// Use a TIFFRGBAImage wrapping the tiff image, and let libtiff handle
|
||||||
// all of the conversion. Metadata read from the TIFFRGBAImage could
|
// all of the conversion. Metadata read from the TIFFRGBAImage could
|
||||||
|
@ -211,8 +239,12 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
img.col_offset = 0;
|
img.col_offset = 0;
|
||||||
|
|
||||||
if (state->xsize != img.width || state->ysize != img.height) {
|
if (state->xsize != img.width || state->ysize != img.height) {
|
||||||
TRACE(("Inconsistent Image Error: %d =? %d, %d =? %d",
|
TRACE(
|
||||||
state->xsize, img.width, state->ysize, img.height));
|
("Inconsistent Image Error: %d =? %d, %d =? %d",
|
||||||
|
state->xsize,
|
||||||
|
img.width,
|
||||||
|
state->ysize,
|
||||||
|
img.height));
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
goto decodeycbcr_err;
|
goto decodeycbcr_err;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +282,8 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
img.row_offset = state->y;
|
img.row_offset = state->y;
|
||||||
rows_to_read = min(rows_per_strip, img.height - state->y);
|
rows_to_read = min(rows_per_strip, img.height - state->y);
|
||||||
|
|
||||||
if (TIFFRGBAImageGet(&img, (UINT32 *)state->buffer, img.width, rows_to_read) == -1) {
|
if (TIFFRGBAImageGet(&img, (UINT32 *)state->buffer, img.width, rows_to_read) ==
|
||||||
|
-1) {
|
||||||
TRACE(("Decode Error, y: %d\n", state->y));
|
TRACE(("Decode Error, y: %d\n", state->y));
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
goto decodeycbcr_err;
|
goto decodeycbcr_err;
|
||||||
|
@ -259,13 +292,17 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
TRACE(("Decoded strip for row %d \n", state->y));
|
TRACE(("Decoded strip for row %d \n", state->y));
|
||||||
|
|
||||||
// iterate over each row in the strip and stuff data into image
|
// iterate over each row in the strip and stuff data into image
|
||||||
for (strip_row = 0; strip_row < min((INT32) rows_per_strip, state->ysize - state->y); strip_row++) {
|
for (strip_row = 0;
|
||||||
|
strip_row < min((INT32)rows_per_strip, state->ysize - state->y);
|
||||||
|
strip_row++) {
|
||||||
TRACE(("Writing data into line %d ; \n", state->y + strip_row));
|
TRACE(("Writing data into line %d ; \n", state->y + strip_row));
|
||||||
|
|
||||||
// UINT8 * bbb = state->buffer + strip_row * (state->bytes / rows_per_strip);
|
// UINT8 * bbb = state->buffer + strip_row * (state->bytes /
|
||||||
// TRACE(("chars: %x %x %x %x\n", ((UINT8 *)bbb)[0], ((UINT8 *)bbb)[1], ((UINT8 *)bbb)[2], ((UINT8 *)bbb)[3]));
|
// rows_per_strip); TRACE(("chars: %x %x %x %x\n", ((UINT8 *)bbb)[0],
|
||||||
|
// ((UINT8 *)bbb)[1], ((UINT8 *)bbb)[2], ((UINT8 *)bbb)[3]));
|
||||||
|
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff + strip_row] +
|
state->shuffle(
|
||||||
|
(UINT8 *)im->image[state->y + state->yoff + strip_row] +
|
||||||
state->xoff * im->pixelsize,
|
state->xoff * im->pixelsize,
|
||||||
state->buffer + strip_row * row_byte_size,
|
state->buffer + strip_row * row_byte_size,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
@ -280,7 +317,8 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
int
|
||||||
|
_decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
INT32 strip_row;
|
INT32 strip_row;
|
||||||
UINT8 *new_data;
|
UINT8 *new_data;
|
||||||
UINT32 rows_per_strip, row_byte_size;
|
UINT32 rows_per_strip, row_byte_size;
|
||||||
|
@ -307,7 +345,8 @@ int _decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
|
|
||||||
if (TIFFStripSize(tiff) > state->bytes) {
|
if (TIFFStripSize(tiff) > state->bytes) {
|
||||||
// If the strip size as expected by LibTiff isn't what we're expecting, abort.
|
// If the strip size as expected by LibTiff isn't what we're expecting, abort.
|
||||||
// man: TIFFStripSize returns the equivalent size for a strip of data as it would be returned in a
|
// man: TIFFStripSize returns the equivalent size for a strip of data as it
|
||||||
|
// would be returned in a
|
||||||
// call to TIFFReadEncodedStrip ...
|
// call to TIFFReadEncodedStrip ...
|
||||||
|
|
||||||
state->errcode = IMAGING_CODEC_MEMORY;
|
state->errcode = IMAGING_CODEC_MEMORY;
|
||||||
|
@ -325,7 +364,11 @@ int _decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
state->buffer = new_data;
|
state->buffer = new_data;
|
||||||
|
|
||||||
for (; state->y < state->ysize; state->y += rows_per_strip) {
|
for (; state->y < state->ysize; state->y += rows_per_strip) {
|
||||||
if (TIFFReadEncodedStrip(tiff, TIFFComputeStrip(tiff, state->y, 0), (tdata_t)state->buffer, -1) == -1) {
|
if (TIFFReadEncodedStrip(
|
||||||
|
tiff,
|
||||||
|
TIFFComputeStrip(tiff, state->y, 0),
|
||||||
|
(tdata_t)state->buffer,
|
||||||
|
-1) == -1) {
|
||||||
TRACE(("Decode Error, strip %d\n", TIFFComputeStrip(tiff, state->y, 0)));
|
TRACE(("Decode Error, strip %d\n", TIFFComputeStrip(tiff, state->y, 0)));
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -334,13 +377,17 @@ int _decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
TRACE(("Decoded strip for row %d \n", state->y));
|
TRACE(("Decoded strip for row %d \n", state->y));
|
||||||
|
|
||||||
// iterate over each row in the strip and stuff data into image
|
// iterate over each row in the strip and stuff data into image
|
||||||
for (strip_row = 0; strip_row < min((INT32) rows_per_strip, state->ysize - state->y); strip_row++) {
|
for (strip_row = 0;
|
||||||
|
strip_row < min((INT32)rows_per_strip, state->ysize - state->y);
|
||||||
|
strip_row++) {
|
||||||
TRACE(("Writing data into line %d ; \n", state->y + strip_row));
|
TRACE(("Writing data into line %d ; \n", state->y + strip_row));
|
||||||
|
|
||||||
// UINT8 * bbb = state->buffer + strip_row * (state->bytes / rows_per_strip);
|
// UINT8 * bbb = state->buffer + strip_row * (state->bytes /
|
||||||
// TRACE(("chars: %x %x %x %x\n", ((UINT8 *)bbb)[0], ((UINT8 *)bbb)[1], ((UINT8 *)bbb)[2], ((UINT8 *)bbb)[3]));
|
// rows_per_strip); TRACE(("chars: %x %x %x %x\n", ((UINT8 *)bbb)[0],
|
||||||
|
// ((UINT8 *)bbb)[1], ((UINT8 *)bbb)[2], ((UINT8 *)bbb)[3]));
|
||||||
|
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff + strip_row] +
|
state->shuffle(
|
||||||
|
(UINT8 *)im->image[state->y + state->yoff + strip_row] +
|
||||||
state->xoff * im->pixelsize,
|
state->xoff * im->pixelsize,
|
||||||
state->buffer + strip_row * row_byte_size,
|
state->buffer + strip_row * row_byte_size,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
@ -349,7 +396,9 @@ int _decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t bytes) {
|
int
|
||||||
|
ImagingLibTiffDecode(
|
||||||
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes) {
|
||||||
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
||||||
char *filename = "tempfile.tif";
|
char *filename = "tempfile.tif";
|
||||||
char *mode = "r";
|
char *mode = "r";
|
||||||
|
@ -361,19 +410,47 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
/* it all ends up in state->buffer, which is a uint8* from Imaging.h */
|
/* it all ends up in state->buffer, which is a uint8* from Imaging.h */
|
||||||
|
|
||||||
TRACE(("in decoder: bytes %d\n", bytes));
|
TRACE(("in decoder: bytes %d\n", bytes));
|
||||||
TRACE(("State: count %d, state %d, x %d, y %d, ystep %d\n", state->count, state->state,
|
TRACE(
|
||||||
state->x, state->y, state->ystep));
|
("State: count %d, state %d, x %d, y %d, ystep %d\n",
|
||||||
TRACE(("State: xsize %d, ysize %d, xoff %d, yoff %d \n", state->xsize, state->ysize,
|
state->count,
|
||||||
state->xoff, state->yoff));
|
state->state,
|
||||||
|
state->x,
|
||||||
|
state->y,
|
||||||
|
state->ystep));
|
||||||
|
TRACE(
|
||||||
|
("State: xsize %d, ysize %d, xoff %d, yoff %d \n",
|
||||||
|
state->xsize,
|
||||||
|
state->ysize,
|
||||||
|
state->xoff,
|
||||||
|
state->yoff));
|
||||||
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
|
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
|
||||||
TRACE(("Buffer: %p: %c%c%c%c\n", buffer, (char)buffer[0], (char)buffer[1],(char)buffer[2], (char)buffer[3]));
|
TRACE(
|
||||||
TRACE(("State->Buffer: %c%c%c%c\n", (char)state->buffer[0], (char)state->buffer[1],(char)state->buffer[2], (char)state->buffer[3]));
|
("Buffer: %p: %c%c%c%c\n",
|
||||||
TRACE(("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
|
buffer,
|
||||||
im->mode, im->type, im->bands, im->xsize, im->ysize));
|
(char)buffer[0],
|
||||||
TRACE(("Image: image8 %p, image32 %p, image %p, block %p \n",
|
(char)buffer[1],
|
||||||
im->image8, im->image32, im->image, im->block));
|
(char)buffer[2],
|
||||||
TRACE(("Image: pixelsize: %d, linesize %d \n",
|
(char)buffer[3]));
|
||||||
im->pixelsize, im->linesize));
|
TRACE(
|
||||||
|
("State->Buffer: %c%c%c%c\n",
|
||||||
|
(char)state->buffer[0],
|
||||||
|
(char)state->buffer[1],
|
||||||
|
(char)state->buffer[2],
|
||||||
|
(char)state->buffer[3]));
|
||||||
|
TRACE(
|
||||||
|
("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
|
||||||
|
im->mode,
|
||||||
|
im->type,
|
||||||
|
im->bands,
|
||||||
|
im->xsize,
|
||||||
|
im->ysize));
|
||||||
|
TRACE(
|
||||||
|
("Image: image8 %p, image32 %p, image %p, block %p \n",
|
||||||
|
im->image8,
|
||||||
|
im->image32,
|
||||||
|
im->image,
|
||||||
|
im->block));
|
||||||
|
TRACE(("Image: pixelsize: %d, linesize %d \n", im->pixelsize, im->linesize));
|
||||||
|
|
||||||
dump_state(clientstate);
|
dump_state(clientstate);
|
||||||
clientstate->size = bytes;
|
clientstate->size = bytes;
|
||||||
|
@ -392,11 +469,17 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
tiff = TIFFFdOpen(fd_to_tiff_fd(clientstate->fp), filename, mode);
|
tiff = TIFFFdOpen(fd_to_tiff_fd(clientstate->fp), filename, mode);
|
||||||
} else {
|
} else {
|
||||||
TRACE(("Opening from string\n"));
|
TRACE(("Opening from string\n"));
|
||||||
tiff = TIFFClientOpen(filename, mode,
|
tiff = TIFFClientOpen(
|
||||||
|
filename,
|
||||||
|
mode,
|
||||||
(thandle_t)clientstate,
|
(thandle_t)clientstate,
|
||||||
_tiffReadProc, _tiffWriteProc,
|
_tiffReadProc,
|
||||||
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
|
_tiffWriteProc,
|
||||||
_tiffMapProc, _tiffUnmapProc);
|
_tiffSeekProc,
|
||||||
|
_tiffCloseProc,
|
||||||
|
_tiffSizeProc,
|
||||||
|
_tiffMapProc,
|
||||||
|
_tiffUnmapProc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tiff) {
|
if (!tiff) {
|
||||||
|
@ -416,13 +499,13 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
|
TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
|
||||||
isYCbCr = photometric == PHOTOMETRIC_YCBCR;
|
isYCbCr = photometric == PHOTOMETRIC_YCBCR;
|
||||||
|
|
||||||
if (TIFFIsTiled(tiff)) {
|
if (TIFFIsTiled(tiff)) {
|
||||||
INT32 x, y, tile_y;
|
INT32 x, y, tile_y;
|
||||||
UINT32 tile_width, tile_length, current_tile_length, current_line, current_tile_width, row_byte_size;
|
UINT32 tile_width, tile_length, current_tile_length, current_line,
|
||||||
|
current_tile_width, row_byte_size;
|
||||||
UINT8 *new_data;
|
UINT8 *new_data;
|
||||||
|
|
||||||
TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tile_width);
|
TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tile_width);
|
||||||
|
@ -434,7 +517,6 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
goto decode_err;
|
goto decode_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isYCbCr) {
|
if (isYCbCr) {
|
||||||
row_byte_size = tile_width * 4;
|
row_byte_size = tile_width * 4;
|
||||||
/* sanity check, we use this value in shuffle below */
|
/* sanity check, we use this value in shuffle below */
|
||||||
|
@ -443,7 +525,8 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
goto decode_err;
|
goto decode_err;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We could use TIFFTileSize, but for YCbCr data it returns subsampled data size
|
// We could use TIFFTileSize, but for YCbCr data it returns subsampled data
|
||||||
|
// size
|
||||||
row_byte_size = (tile_width * state->bits + 7) / 8;
|
row_byte_size = (tile_width * state->bits + 7) / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +539,8 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
state->bytes = row_byte_size * tile_length;
|
state->bytes = row_byte_size * tile_length;
|
||||||
|
|
||||||
if (TIFFTileSize(tiff) > state->bytes) {
|
if (TIFFTileSize(tiff) > state->bytes) {
|
||||||
// If the strip size as expected by LibTiff isn't what we're expecting, abort.
|
// If the strip size as expected by LibTiff isn't what we're expecting,
|
||||||
|
// abort.
|
||||||
state->errcode = IMAGING_CODEC_MEMORY;
|
state->errcode = IMAGING_CODEC_MEMORY;
|
||||||
goto decode_err;
|
goto decode_err;
|
||||||
}
|
}
|
||||||
|
@ -496,10 +580,15 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
current_tile_length = min((INT32)tile_length, state->ysize - y);
|
current_tile_length = min((INT32)tile_length, state->ysize - y);
|
||||||
// iterate over each line in the tile and stuff data into image
|
// iterate over each line in the tile and stuff data into image
|
||||||
for (tile_y = 0; tile_y < current_tile_length; tile_y++) {
|
for (tile_y = 0; tile_y < current_tile_length; tile_y++) {
|
||||||
TRACE(("Writing tile data at %dx%d using tile_width: %d; \n", tile_y + y, x, current_tile_width));
|
TRACE(
|
||||||
|
("Writing tile data at %dx%d using tile_width: %d; \n",
|
||||||
|
tile_y + y,
|
||||||
|
x,
|
||||||
|
current_tile_width));
|
||||||
|
|
||||||
// UINT8 * bbb = state->buffer + tile_y * row_byte_size;
|
// UINT8 * bbb = state->buffer + tile_y * row_byte_size;
|
||||||
// TRACE(("chars: %x%x%x%x\n", ((UINT8 *)bbb)[0], ((UINT8 *)bbb)[1], ((UINT8 *)bbb)[2], ((UINT8 *)bbb)[3]));
|
// TRACE(("chars: %x%x%x%x\n", ((UINT8 *)bbb)[0], ((UINT8 *)bbb)[1],
|
||||||
|
// ((UINT8 *)bbb)[2], ((UINT8 *)bbb)[3]));
|
||||||
/*
|
/*
|
||||||
* For some reason the TIFFReadRGBATile() function
|
* For some reason the TIFFReadRGBATile() function
|
||||||
* chooses the lower left corner as the origin.
|
* chooses the lower left corner as the origin.
|
||||||
|
@ -513,18 +602,17 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
current_line = tile_y;
|
current_line = tile_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->shuffle((UINT8*) im->image[tile_y + y] + x * im->pixelsize,
|
state->shuffle(
|
||||||
|
(UINT8 *)im->image[tile_y + y] + x * im->pixelsize,
|
||||||
state->buffer + current_line * row_byte_size,
|
state->buffer + current_line * row_byte_size,
|
||||||
current_tile_width
|
current_tile_width);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!isYCbCr) {
|
if (!isYCbCr) {
|
||||||
_decodeStrip(im, state, tiff);
|
_decodeStrip(im, state, tiff);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_decodeStripYCbCr(im, state, tiff);
|
_decodeStripYCbCr(im, state, tiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,7 +625,8 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
|
int
|
||||||
|
ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
|
||||||
// Open the FD or the pointer as a tiff file, for writing.
|
// Open the FD or the pointer as a tiff file, for writing.
|
||||||
// We may have to do some monkeying around to make this really work.
|
// We may have to do some monkeying around to make this really work.
|
||||||
// If we have a fp, then we're good.
|
// If we have a fp, then we're good.
|
||||||
|
@ -551,10 +640,19 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
|
||||||
|
|
||||||
TRACE(("initing libtiff\n"));
|
TRACE(("initing libtiff\n"));
|
||||||
TRACE(("Filename %s, filepointer: %d \n", filename, fp));
|
TRACE(("Filename %s, filepointer: %d \n", filename, fp));
|
||||||
TRACE(("State: count %d, state %d, x %d, y %d, ystep %d\n", state->count, state->state,
|
TRACE(
|
||||||
state->x, state->y, state->ystep));
|
("State: count %d, state %d, x %d, y %d, ystep %d\n",
|
||||||
TRACE(("State: xsize %d, ysize %d, xoff %d, yoff %d \n", state->xsize, state->ysize,
|
state->count,
|
||||||
state->xoff, state->yoff));
|
state->state,
|
||||||
|
state->x,
|
||||||
|
state->y,
|
||||||
|
state->ystep));
|
||||||
|
TRACE(
|
||||||
|
("State: xsize %d, ysize %d, xoff %d, yoff %d \n",
|
||||||
|
state->xsize,
|
||||||
|
state->ysize,
|
||||||
|
state->xoff,
|
||||||
|
state->yoff));
|
||||||
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
|
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
|
||||||
TRACE(("State: context %p \n", state->context));
|
TRACE(("State: context %p \n", state->context));
|
||||||
|
|
||||||
|
@ -571,7 +669,8 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
|
||||||
TRACE(("Opening using fd: %d for writing \n", clientstate->fp));
|
TRACE(("Opening using fd: %d for writing \n", clientstate->fp));
|
||||||
clientstate->tiff = TIFFFdOpen(fd_to_tiff_fd(clientstate->fp), filename, mode);
|
clientstate->tiff = TIFFFdOpen(fd_to_tiff_fd(clientstate->fp), filename, mode);
|
||||||
} else {
|
} else {
|
||||||
// malloc a buffer to write the tif, we're going to need to realloc or something if we need bigger.
|
// malloc a buffer to write the tif, we're going to need to realloc or something
|
||||||
|
// if we need bigger.
|
||||||
TRACE(("Opening a buffer for writing \n"));
|
TRACE(("Opening a buffer for writing \n"));
|
||||||
/* malloc check ok, small constant allocation */
|
/* malloc check ok, small constant allocation */
|
||||||
clientstate->data = malloc(bufsize);
|
clientstate->data = malloc(bufsize);
|
||||||
|
@ -583,12 +682,17 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
clientstate->tiff = TIFFClientOpen(filename, mode,
|
clientstate->tiff = TIFFClientOpen(
|
||||||
|
filename,
|
||||||
|
mode,
|
||||||
(thandle_t)clientstate,
|
(thandle_t)clientstate,
|
||||||
_tiffReadProc, _tiffWriteProc,
|
_tiffReadProc,
|
||||||
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
|
_tiffWriteProc,
|
||||||
_tiffNullMapProc, _tiffUnmapProc); /*force no mmap*/
|
_tiffSeekProc,
|
||||||
|
_tiffCloseProc,
|
||||||
|
_tiffSizeProc,
|
||||||
|
_tiffNullMapProc,
|
||||||
|
_tiffUnmapProc); /*force no mmap*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clientstate->tiff) {
|
if (!clientstate->tiff) {
|
||||||
|
@ -597,10 +701,11 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImagingLibTiffMergeFieldInfo(ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length){
|
int
|
||||||
|
ImagingLibTiffMergeFieldInfo(
|
||||||
|
ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length) {
|
||||||
// Refer to libtiff docs (http://www.simplesystems.org/libtiff/addingtags.html)
|
// Refer to libtiff docs (http://www.simplesystems.org/libtiff/addingtags.html)
|
||||||
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
||||||
uint32 n;
|
uint32 n;
|
||||||
|
@ -615,8 +720,14 @@ int ImagingLibTiffMergeFieldInfo(ImagingCodecState state, TIFFDataType field_typ
|
||||||
int passcount = 0;
|
int passcount = 0;
|
||||||
|
|
||||||
TIFFFieldInfo info[] = {
|
TIFFFieldInfo info[] = {
|
||||||
{ key, readcount, writecount, field_type, FIELD_CUSTOM, 1, passcount, "CustomField" }
|
{key,
|
||||||
};
|
readcount,
|
||||||
|
writecount,
|
||||||
|
field_type,
|
||||||
|
FIELD_CUSTOM,
|
||||||
|
1,
|
||||||
|
passcount,
|
||||||
|
"CustomField"}};
|
||||||
|
|
||||||
if (is_var_length) {
|
if (is_var_length) {
|
||||||
info[0].field_writecount = -1;
|
info[0].field_writecount = -1;
|
||||||
|
@ -629,7 +740,8 @@ int ImagingLibTiffMergeFieldInfo(ImagingCodecState state, TIFFDataType field_typ
|
||||||
n = sizeof(info) / sizeof(info[0]);
|
n = sizeof(info) / sizeof(info[0]);
|
||||||
|
|
||||||
// Test for libtiff 4.0 or later, excluding libtiff 3.9.6 and 3.9.7
|
// Test for libtiff 4.0 or later, excluding libtiff 3.9.6 and 3.9.7
|
||||||
#if TIFFLIB_VERSION >= 20111221 && TIFFLIB_VERSION != 20120218 && TIFFLIB_VERSION != 20120922
|
#if TIFFLIB_VERSION >= 20111221 && TIFFLIB_VERSION != 20120218 && \
|
||||||
|
TIFFLIB_VERSION != 20120922
|
||||||
status = TIFFMergeFieldInfo(clientstate->tiff, info, n);
|
status = TIFFMergeFieldInfo(clientstate->tiff, info, n);
|
||||||
#else
|
#else
|
||||||
TIFFMergeFieldInfo(clientstate->tiff, info, n);
|
TIFFMergeFieldInfo(clientstate->tiff, info, n);
|
||||||
|
@ -637,7 +749,8 @@ int ImagingLibTiffMergeFieldInfo(ImagingCodecState state, TIFFDataType field_typ
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...){
|
int
|
||||||
|
ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...) {
|
||||||
// after tif_dir.c->TIFFSetField.
|
// after tif_dir.c->TIFFSetField.
|
||||||
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -649,8 +762,8 @@ int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...){
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
int ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes) {
|
ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes) {
|
||||||
/* One shot encoder. Encode everything to the tiff in the clientstate.
|
/* One shot encoder. Encode everything to the tiff in the clientstate.
|
||||||
If we're running off of a FD, then run once, we're good, everything
|
If we're running off of a FD, then run once, we're good, everything
|
||||||
ends up in the file, we close and we're done.
|
ends up in the file, we close and we're done.
|
||||||
|
@ -664,31 +777,61 @@ int ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8* buffer, int
|
||||||
TIFF *tiff = clientstate->tiff;
|
TIFF *tiff = clientstate->tiff;
|
||||||
|
|
||||||
TRACE(("in encoder: bytes %d\n", bytes));
|
TRACE(("in encoder: bytes %d\n", bytes));
|
||||||
TRACE(("State: count %d, state %d, x %d, y %d, ystep %d\n", state->count, state->state,
|
TRACE(
|
||||||
state->x, state->y, state->ystep));
|
("State: count %d, state %d, x %d, y %d, ystep %d\n",
|
||||||
TRACE(("State: xsize %d, ysize %d, xoff %d, yoff %d \n", state->xsize, state->ysize,
|
state->count,
|
||||||
state->xoff, state->yoff));
|
state->state,
|
||||||
|
state->x,
|
||||||
|
state->y,
|
||||||
|
state->ystep));
|
||||||
|
TRACE(
|
||||||
|
("State: xsize %d, ysize %d, xoff %d, yoff %d \n",
|
||||||
|
state->xsize,
|
||||||
|
state->ysize,
|
||||||
|
state->xoff,
|
||||||
|
state->yoff));
|
||||||
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
|
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
|
||||||
TRACE(("Buffer: %p: %c%c%c%c\n", buffer, (char)buffer[0], (char)buffer[1],(char)buffer[2], (char)buffer[3]));
|
TRACE(
|
||||||
TRACE(("State->Buffer: %c%c%c%c\n", (char)state->buffer[0], (char)state->buffer[1],(char)state->buffer[2], (char)state->buffer[3]));
|
("Buffer: %p: %c%c%c%c\n",
|
||||||
TRACE(("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
|
buffer,
|
||||||
im->mode, im->type, im->bands, im->xsize, im->ysize));
|
(char)buffer[0],
|
||||||
TRACE(("Image: image8 %p, image32 %p, image %p, block %p \n",
|
(char)buffer[1],
|
||||||
im->image8, im->image32, im->image, im->block));
|
(char)buffer[2],
|
||||||
TRACE(("Image: pixelsize: %d, linesize %d \n",
|
(char)buffer[3]));
|
||||||
im->pixelsize, im->linesize));
|
TRACE(
|
||||||
|
("State->Buffer: %c%c%c%c\n",
|
||||||
|
(char)state->buffer[0],
|
||||||
|
(char)state->buffer[1],
|
||||||
|
(char)state->buffer[2],
|
||||||
|
(char)state->buffer[3]));
|
||||||
|
TRACE(
|
||||||
|
("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
|
||||||
|
im->mode,
|
||||||
|
im->type,
|
||||||
|
im->bands,
|
||||||
|
im->xsize,
|
||||||
|
im->ysize));
|
||||||
|
TRACE(
|
||||||
|
("Image: image8 %p, image32 %p, image %p, block %p \n",
|
||||||
|
im->image8,
|
||||||
|
im->image32,
|
||||||
|
im->image,
|
||||||
|
im->block));
|
||||||
|
TRACE(("Image: pixelsize: %d, linesize %d \n", im->pixelsize, im->linesize));
|
||||||
|
|
||||||
dump_state(clientstate);
|
dump_state(clientstate);
|
||||||
|
|
||||||
if (state->state == 0) {
|
if (state->state == 0) {
|
||||||
TRACE(("Encoding line bt line"));
|
TRACE(("Encoding line bt line"));
|
||||||
while (state->y < state->ysize) {
|
while (state->y < state->ysize) {
|
||||||
state->shuffle(state->buffer,
|
state->shuffle(
|
||||||
|
state->buffer,
|
||||||
(UINT8 *)im->image[state->y + state->yoff] +
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
state->xoff * im->pixelsize,
|
state->xoff * im->pixelsize,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
|
||||||
if (TIFFWriteScanline(tiff, (tdata_t)(state->buffer), (uint32)state->y, 0) == -1) {
|
if (TIFFWriteScanline(
|
||||||
|
tiff, (tdata_t)(state->buffer), (uint32)state->y, 0) == -1) {
|
||||||
TRACE(("Encode Error, row %d\n", state->y));
|
TRACE(("Encode Error, row %d\n", state->y));
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
TIFFClose(tiff);
|
TIFFClose(tiff);
|
||||||
|
@ -724,7 +867,13 @@ int ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8* buffer, int
|
||||||
|
|
||||||
if (state->state == 1 && !clientstate->fp) {
|
if (state->state == 1 && !clientstate->fp) {
|
||||||
int read = (int)_tiffReadProc(clientstate, (tdata_t)buffer, (tsize_t)bytes);
|
int read = (int)_tiffReadProc(clientstate, (tdata_t)buffer, (tsize_t)bytes);
|
||||||
TRACE(("Buffer: %p: %c%c%c%c\n", buffer, (char)buffer[0], (char)buffer[1],(char)buffer[2], (char)buffer[3]));
|
TRACE(
|
||||||
|
("Buffer: %p: %c%c%c%c\n",
|
||||||
|
buffer,
|
||||||
|
(char)buffer[0],
|
||||||
|
(char)buffer[1],
|
||||||
|
(char)buffer[2],
|
||||||
|
(char)buffer[3]));
|
||||||
if (clientstate->loc == clientstate->eof) {
|
if (clientstate->loc == clientstate->eof) {
|
||||||
TRACE(("Hit EOF, calling an end, freeing data"));
|
TRACE(("Hit EOF, calling an end, freeing data"));
|
||||||
state->errcode = IMAGING_CODEC_END;
|
state->errcode = IMAGING_CODEC_END;
|
||||||
|
@ -738,8 +887,7 @@ int ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8* buffer, int
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
ImagingTiffVersion(void)
|
ImagingTiffVersion(void) {
|
||||||
{
|
|
||||||
return TIFFGetVersion();
|
return TIFFGetVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,13 +41,15 @@ typedef struct {
|
||||||
int flrealloc; /* may we realloc */
|
int flrealloc; /* may we realloc */
|
||||||
} TIFFSTATE;
|
} TIFFSTATE;
|
||||||
|
|
||||||
|
extern int
|
||||||
|
ImagingLibTiffInit(ImagingCodecState state, int fp, uint32 offset);
|
||||||
extern int ImagingLibTiffInit(ImagingCodecState state, int fp, uint32 offset);
|
extern int
|
||||||
extern int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp);
|
ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp);
|
||||||
extern int ImagingLibTiffMergeFieldInfo(ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length);
|
extern int
|
||||||
extern int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...);
|
ImagingLibTiffMergeFieldInfo(
|
||||||
|
ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length);
|
||||||
|
extern int
|
||||||
|
ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Trace debugging
|
Trace debugging
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,115 +13,116 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
/* Tables generated by pcdtables.py, based on transforms taken from
|
/* Tables generated by pcdtables.py, based on transforms taken from
|
||||||
the "Colour Space Conversions FAQ" by Roberts/Ford. */
|
the "Colour Space Conversions FAQ" by Roberts/Ford. */
|
||||||
|
|
||||||
static INT16 L[] = { 0, 1, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 16, 18,
|
static INT16 L[] = {
|
||||||
19, 20, 22, 23, 24, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41,
|
0, 1, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 16, 18, 19, 20,
|
||||||
42, 43, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 62, 64,
|
22, 23, 24, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, 42,
|
||||||
65, 67, 68, 69, 71, 72, 73, 75, 76, 77, 79, 80, 82, 83, 84, 86, 87,
|
43, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 62, 64,
|
||||||
88, 90, 91, 92, 94, 95, 96, 98, 99, 101, 102, 103, 105, 106, 107, 109,
|
65, 67, 68, 69, 71, 72, 73, 75, 76, 77, 79, 80, 82, 83, 84, 86,
|
||||||
110, 111, 113, 114, 115, 117, 118, 120, 121, 122, 124, 125, 126, 128,
|
87, 88, 90, 91, 92, 94, 95, 96, 98, 99, 101, 102, 103, 105, 106, 107,
|
||||||
129, 130, 132, 133, 134, 136, 137, 139, 140, 141, 143, 144, 145, 147,
|
109, 110, 111, 113, 114, 115, 117, 118, 120, 121, 122, 124, 125, 126, 128, 129,
|
||||||
148, 149, 151, 152, 153, 155, 156, 158, 159, 160, 162, 163, 164, 166,
|
130, 132, 133, 134, 136, 137, 139, 140, 141, 143, 144, 145, 147, 148, 149, 151,
|
||||||
167, 168, 170, 171, 173, 174, 175, 177, 178, 179, 181, 182, 183, 185,
|
152, 153, 155, 156, 158, 159, 160, 162, 163, 164, 166, 167, 168, 170, 171, 173,
|
||||||
186, 187, 189, 190, 192, 193, 194, 196, 197, 198, 200, 201, 202, 204,
|
174, 175, 177, 178, 179, 181, 182, 183, 185, 186, 187, 189, 190, 192, 193, 194,
|
||||||
205, 206, 208, 209, 211, 212, 213, 215, 216, 217, 219, 220, 221, 223,
|
196, 197, 198, 200, 201, 202, 204, 205, 206, 208, 209, 211, 212, 213, 215, 216,
|
||||||
224, 225, 227, 228, 230, 231, 232, 234, 235, 236, 238, 239, 240, 242,
|
217, 219, 220, 221, 223, 224, 225, 227, 228, 230, 231, 232, 234, 235, 236, 238,
|
||||||
243, 245, 246, 247, 249, 250, 251, 253, 254, 255, 257, 258, 259, 261,
|
239, 240, 242, 243, 245, 246, 247, 249, 250, 251, 253, 254, 255, 257, 258, 259,
|
||||||
262, 264, 265, 266, 268, 269, 270, 272, 273, 274, 276, 277, 278, 280,
|
261, 262, 264, 265, 266, 268, 269, 270, 272, 273, 274, 276, 277, 278, 280, 281,
|
||||||
281, 283, 284, 285, 287, 288, 289, 291, 292, 293, 295, 296, 297, 299,
|
283, 284, 285, 287, 288, 289, 291, 292, 293, 295, 296, 297, 299, 300, 302, 303,
|
||||||
300, 302, 303, 304, 306, 307, 308, 310, 311, 312, 314, 315, 317, 318,
|
304, 306, 307, 308, 310, 311, 312, 314, 315, 317, 318, 319, 321, 322, 323, 325,
|
||||||
319, 321, 322, 323, 325, 326, 327, 329, 330, 331, 333, 334, 336, 337,
|
326, 327, 329, 330, 331, 333, 334, 336, 337, 338, 340, 341, 342, 344, 345, 346};
|
||||||
338, 340, 341, 342, 344, 345, 346 };
|
|
||||||
|
|
||||||
static INT16 CB[] = { -345, -343, -341, -338, -336, -334, -332, -329,
|
static INT16 CB[] = {
|
||||||
-327, -325, -323, -321, -318, -316, -314, -312, -310, -307, -305,
|
-345, -343, -341, -338, -336, -334, -332, -329, -327, -325, -323, -321, -318, -316,
|
||||||
-303, -301, -298, -296, -294, -292, -290, -287, -285, -283, -281,
|
-314, -312, -310, -307, -305, -303, -301, -298, -296, -294, -292, -290, -287, -285,
|
||||||
-278, -276, -274, -272, -270, -267, -265, -263, -261, -258, -256,
|
-283, -281, -278, -276, -274, -272, -270, -267, -265, -263, -261, -258, -256, -254,
|
||||||
-254, -252, -250, -247, -245, -243, -241, -239, -236, -234, -232,
|
-252, -250, -247, -245, -243, -241, -239, -236, -234, -232, -230, -227, -225, -223,
|
||||||
-230, -227, -225, -223, -221, -219, -216, -214, -212, -210, -207,
|
-221, -219, -216, -214, -212, -210, -207, -205, -203, -201, -199, -196, -194, -192,
|
||||||
-205, -203, -201, -199, -196, -194, -192, -190, -188, -185, -183,
|
-190, -188, -185, -183, -181, -179, -176, -174, -172, -170, -168, -165, -163, -161,
|
||||||
-181, -179, -176, -174, -172, -170, -168, -165, -163, -161, -159,
|
-159, -156, -154, -152, -150, -148, -145, -143, -141, -139, -137, -134, -132, -130,
|
||||||
-156, -154, -152, -150, -148, -145, -143, -141, -139, -137, -134,
|
-128, -125, -123, -121, -119, -117, -114, -112, -110, -108, -105, -103, -101, -99,
|
||||||
-132, -130, -128, -125, -123, -121, -119, -117, -114, -112, -110,
|
-97, -94, -92, -90, -88, -85, -83, -81, -79, -77, -74, -72, -70, -68,
|
||||||
-108, -105, -103, -101, -99, -97, -94, -92, -90, -88, -85, -83, -81,
|
-66, -63, -61, -59, -57, -54, -52, -50, -48, -46, -43, -41, -39, -37,
|
||||||
-79, -77, -74, -72, -70, -68, -66, -63, -61, -59, -57, -54, -52, -50,
|
-34, -32, -30, -28, -26, -23, -21, -19, -17, -15, -12, -10, -8, -6,
|
||||||
-48, -46, -43, -41, -39, -37, -34, -32, -30, -28, -26, -23, -21, -19,
|
-3, -1, 0, 2, 4, 7, 9, 11, 13, 16, 18, 20, 22, 24,
|
||||||
-17, -15, -12, -10, -8, -6, -3, -1, 0, 2, 4, 7, 9, 11, 13, 16, 18, 20,
|
27, 29, 31, 33, 35, 38, 40, 42, 44, 47, 49, 51, 53, 55,
|
||||||
22, 24, 27, 29, 31, 33, 35, 38, 40, 42, 44, 47, 49, 51, 53, 55, 58,
|
58, 60, 62, 64, 67, 69, 71, 73, 75, 78, 80, 82, 84, 86,
|
||||||
60, 62, 64, 67, 69, 71, 73, 75, 78, 80, 82, 84, 86, 89, 91, 93, 95,
|
89, 91, 93, 95, 98, 100, 102, 104, 106, 109, 111, 113, 115, 118,
|
||||||
98, 100, 102, 104, 106, 109, 111, 113, 115, 118, 120, 122, 124, 126,
|
120, 122, 124, 126, 129, 131, 133, 135, 138, 140, 142, 144, 146, 149,
|
||||||
129, 131, 133, 135, 138, 140, 142, 144, 146, 149, 151, 153, 155, 157,
|
151, 153, 155, 157, 160, 162, 164, 166, 169, 171, 173, 175, 177, 180,
|
||||||
160, 162, 164, 166, 169, 171, 173, 175, 177, 180, 182, 184, 186, 189,
|
182, 184, 186, 189, 191, 193, 195, 197, 200, 202, 204, 206, 208, 211,
|
||||||
191, 193, 195, 197, 200, 202, 204, 206, 208, 211, 213, 215, 217, 220 };
|
213, 215, 217, 220};
|
||||||
|
|
||||||
static INT16 GB[] = { 67, 67, 66, 66, 65, 65, 65, 64, 64, 63, 63, 62,
|
static INT16 GB[] = {
|
||||||
62, 62, 61, 61, 60, 60, 59, 59, 59, 58, 58, 57, 57, 56, 56, 56, 55,
|
67, 67, 66, 66, 65, 65, 65, 64, 64, 63, 63, 62, 62, 62, 61, 61,
|
||||||
55, 54, 54, 53, 53, 52, 52, 52, 51, 51, 50, 50, 49, 49, 49, 48, 48,
|
60, 60, 59, 59, 59, 58, 58, 57, 57, 56, 56, 56, 55, 55, 54, 54,
|
||||||
47, 47, 46, 46, 46, 45, 45, 44, 44, 43, 43, 43, 42, 42, 41, 41, 40,
|
53, 53, 52, 52, 52, 51, 51, 50, 50, 49, 49, 49, 48, 48, 47, 47,
|
||||||
40, 40, 39, 39, 38, 38, 37, 37, 37, 36, 36, 35, 35, 34, 34, 34, 33,
|
46, 46, 46, 45, 45, 44, 44, 43, 43, 43, 42, 42, 41, 41, 40, 40,
|
||||||
33, 32, 32, 31, 31, 31, 30, 30, 29, 29, 28, 28, 28, 27, 27, 26, 26,
|
40, 39, 39, 38, 38, 37, 37, 37, 36, 36, 35, 35, 34, 34, 34, 33,
|
||||||
25, 25, 25, 24, 24, 23, 23, 22, 22, 22, 21, 21, 20, 20, 19, 19, 19,
|
33, 32, 32, 31, 31, 31, 30, 30, 29, 29, 28, 28, 28, 27, 27, 26,
|
||||||
18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 13, 13, 12, 12, 12, 11,
|
26, 25, 25, 25, 24, 24, 23, 23, 22, 22, 22, 21, 21, 20, 20, 19,
|
||||||
11, 10, 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 4, 4, 3, 3, 3, 2, 2,
|
19, 19, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 13, 13, 12,
|
||||||
1, 1, 0, 0, 0, 0, 0, -1, -1, -2, -2, -2, -3, -3, -4, -4, -5, -5, -5,
|
12, 12, 11, 11, 10, 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 6,
|
||||||
-6, -6, -7, -7, -8, -8, -8, -9, -9, -10, -10, -11, -11, -11, -12, -12,
|
5, 5, 4, 4, 3, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0,
|
||||||
-13, -13, -14, -14, -14, -15, -15, -16, -16, -17, -17, -18, -18, -18,
|
-1, -1, -2, -2, -2, -3, -3, -4, -4, -5, -5, -5, -6, -6, -7, -7,
|
||||||
-19, -19, -20, -20, -21, -21, -21, -22, -22, -23, -23, -24, -24, -24,
|
-8, -8, -8, -9, -9, -10, -10, -11, -11, -11, -12, -12, -13, -13, -14, -14,
|
||||||
-25, -25, -26, -26, -27, -27, -27, -28, -28, -29, -29, -30, -30, -30,
|
-14, -15, -15, -16, -16, -17, -17, -18, -18, -18, -19, -19, -20, -20, -21, -21,
|
||||||
-31, -31, -32, -32, -33, -33, -33, -34, -34, -35, -35, -36, -36, -36,
|
-21, -22, -22, -23, -23, -24, -24, -24, -25, -25, -26, -26, -27, -27, -27, -28,
|
||||||
-37, -37, -38, -38, -39, -39, -39, -40, -40, -41, -41, -42 };
|
-28, -29, -29, -30, -30, -30, -31, -31, -32, -32, -33, -33, -33, -34, -34, -35,
|
||||||
|
-35, -36, -36, -36, -37, -37, -38, -38, -39, -39, -39, -40, -40, -41, -41, -42};
|
||||||
|
|
||||||
static INT16 CR[] = { -249, -247, -245, -243, -241, -239, -238, -236,
|
static INT16 CR[] = {
|
||||||
-234, -232, -230, -229, -227, -225, -223, -221, -219, -218, -216,
|
-249, -247, -245, -243, -241, -239, -238, -236, -234, -232, -230, -229, -227, -225,
|
||||||
-214, -212, -210, -208, -207, -205, -203, -201, -199, -198, -196,
|
-223, -221, -219, -218, -216, -214, -212, -210, -208, -207, -205, -203, -201, -199,
|
||||||
-194, -192, -190, -188, -187, -185, -183, -181, -179, -178, -176,
|
-198, -196, -194, -192, -190, -188, -187, -185, -183, -181, -179, -178, -176, -174,
|
||||||
-174, -172, -170, -168, -167, -165, -163, -161, -159, -157, -156,
|
-172, -170, -168, -167, -165, -163, -161, -159, -157, -156, -154, -152, -150, -148,
|
||||||
-154, -152, -150, -148, -147, -145, -143, -141, -139, -137, -136,
|
-147, -145, -143, -141, -139, -137, -136, -134, -132, -130, -128, -127, -125, -123,
|
||||||
-134, -132, -130, -128, -127, -125, -123, -121, -119, -117, -116,
|
-121, -119, -117, -116, -114, -112, -110, -108, -106, -105, -103, -101, -99, -97,
|
||||||
-114, -112, -110, -108, -106, -105, -103, -101, -99, -97, -96, -94,
|
-96, -94, -92, -90, -88, -86, -85, -83, -81, -79, -77, -76, -74, -72,
|
||||||
-92, -90, -88, -86, -85, -83, -81, -79, -77, -76, -74, -72, -70, -68,
|
-70, -68, -66, -65, -63, -61, -59, -57, -55, -54, -52, -50, -48, -46,
|
||||||
-66, -65, -63, -61, -59, -57, -55, -54, -52, -50, -48, -46, -45, -43,
|
-45, -43, -41, -39, -37, -35, -34, -32, -30, -28, -26, -25, -23, -21,
|
||||||
-41, -39, -37, -35, -34, -32, -30, -28, -26, -25, -23, -21, -19, -17,
|
-19, -17, -15, -14, -12, -10, -8, -6, -4, -3, -1, 0, 2, 4,
|
||||||
-15, -14, -12, -10, -8, -6, -4, -3, -1, 0, 2, 4, 5, 7, 9, 11, 13, 15,
|
5, 7, 9, 11, 13, 15, 16, 18, 20, 22, 24, 26, 27, 29,
|
||||||
16, 18, 20, 22, 24, 26, 27, 29, 31, 33, 35, 36, 38, 40, 42, 44, 46,
|
31, 33, 35, 36, 38, 40, 42, 44, 46, 47, 49, 51, 53, 55,
|
||||||
47, 49, 51, 53, 55, 56, 58, 60, 62, 64, 66, 67, 69, 71, 73, 75, 77,
|
56, 58, 60, 62, 64, 66, 67, 69, 71, 73, 75, 77, 78, 80,
|
||||||
78, 80, 82, 84, 86, 87, 89, 91, 93, 95, 97, 98, 100, 102, 104, 106,
|
82, 84, 86, 87, 89, 91, 93, 95, 97, 98, 100, 102, 104, 106,
|
||||||
107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 129, 131,
|
107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 129, 131,
|
||||||
133, 135, 137, 138, 140, 142, 144, 146, 148, 149, 151, 153, 155, 157,
|
133, 135, 137, 138, 140, 142, 144, 146, 148, 149, 151, 153, 155, 157,
|
||||||
158, 160, 162, 164, 166, 168, 169, 171, 173, 175, 177, 179, 180, 182,
|
158, 160, 162, 164, 166, 168, 169, 171, 173, 175, 177, 179, 180, 182,
|
||||||
184, 186, 188, 189, 191, 193, 195, 197, 199, 200, 202, 204, 206, 208,
|
184, 186, 188, 189, 191, 193, 195, 197, 199, 200, 202, 204, 206, 208,
|
||||||
209, 211, 213, 215};
|
209, 211, 213, 215};
|
||||||
|
|
||||||
static INT16 GR[] = { 127, 126, 125, 124, 123, 122, 121, 121, 120, 119,
|
static INT16 GR[] = {
|
||||||
118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 108, 107, 106,
|
127, 126, 125, 124, 123, 122, 121, 121, 120, 119, 118, 117, 116, 115, 114,
|
||||||
105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 95, 94, 93, 92, 91,
|
113, 112, 111, 110, 109, 108, 108, 107, 106, 105, 104, 103, 102, 101, 100,
|
||||||
90, 89, 88, 87, 86, 85, 84, 83, 83, 82, 81, 80, 79, 78, 77, 76, 75,
|
99, 98, 97, 96, 95, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86,
|
||||||
74, 73, 72, 71, 70, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59,
|
85, 84, 83, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72,
|
||||||
58, 57, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 45, 44,
|
71, 70, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58,
|
||||||
43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 32, 31, 30, 29, 28,
|
57, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 45,
|
||||||
27, 26, 25, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12,
|
44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 32, 31,
|
||||||
11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5, -5,
|
30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 19, 18, 17,
|
||||||
-6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -18, -19,
|
16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 3,
|
||||||
-20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -31, -31, -32,
|
2, 1, 0, 0, -1, -2, -3, -4, -5, -5, -6, -7, -8, -9, -10,
|
||||||
-33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, -44, -44, -45,
|
-11, -12, -13, -14, -15, -16, -17, -18, -18, -19, -20, -21, -22, -23, -24,
|
||||||
-46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -56, -57, -58,
|
-25, -26, -27, -28, -29, -30, -31, -31, -32, -33, -34, -35, -36, -37, -38,
|
||||||
-59, -60, -61, -62, -63, -64, -65, -66, -67, -68, -69, -69, -70, -71,
|
-39, -40, -41, -42, -43, -44, -44, -45, -46, -47, -48, -49, -50, -51, -52,
|
||||||
-72, -73, -74, -75, -76, -77, -78, -79, -80, -81, -82, -82, -83, -84,
|
-53, -54, -55, -56, -56, -57, -58, -59, -60, -61, -62, -63, -64, -65, -66,
|
||||||
-85, -86, -87, -88, -89, -90, -91, -92, -93, -94, -94, -95, -96, -97,
|
-67, -68, -69, -69, -70, -71, -72, -73, -74, -75, -76, -77, -78, -79, -80,
|
||||||
-98, -99, -100, -101, -102, -103, -104, -105, -106, -107, -107, -108 };
|
-81, -82, -82, -83, -84, -85, -86, -87, -88, -89, -90, -91, -92, -93, -94,
|
||||||
|
-94, -95, -96, -97, -98, -99, -100, -101, -102, -103, -104, -105, -106, -107, -107,
|
||||||
|
-108};
|
||||||
|
|
||||||
#define R 0
|
#define R 0
|
||||||
#define G 1
|
#define G 1
|
||||||
#define B 2
|
#define B 2
|
||||||
#define A 3
|
#define A 3
|
||||||
|
|
||||||
#define YCC2RGB(rgb, y, cb, cr) {\
|
#define YCC2RGB(rgb, y, cb, cr) \
|
||||||
|
{ \
|
||||||
int l = L[y]; \
|
int l = L[y]; \
|
||||||
int r = l + CR[cr]; \
|
int r = l + CR[cr]; \
|
||||||
int g = l + GR[cr] + GB[cb]; \
|
int g = l + GR[cr] + GB[cb]; \
|
||||||
|
@ -132,20 +133,19 @@ static INT16 GR[] = { 127, 126, 125, 124, 123, 122, 121, 121, 120, 119,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingUnpackYCC(UINT8* out, const UINT8* in, int pixels)
|
ImagingUnpackYCC(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* PhotoYCC triplets */
|
/* PhotoYCC triplets */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
YCC2RGB(out, in[0], in[1], in[2]);
|
YCC2RGB(out, in[0], in[1], in[2]);
|
||||||
out[A] = 255;
|
out[A] = 255;
|
||||||
out += 4; in += 3;
|
out += 4;
|
||||||
|
in += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels)
|
ImagingUnpackYCCA(UINT8 *out, const UINT8 *in, int pixels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* PhotoYCC triplets plus premultiplied alpha */
|
/* PhotoYCC triplets plus premultiplied alpha */
|
||||||
for (i = 0; i < pixels; i++) {
|
for (i = 0; i < pixels; i++) {
|
||||||
|
@ -157,6 +157,7 @@ ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels)
|
||||||
/* Convert non-multiplied data to RGB */
|
/* Convert non-multiplied data to RGB */
|
||||||
YCC2RGB(out, rgb[0], rgb[1], rgb[2]);
|
YCC2RGB(out, rgb[0], rgb[1], rgb[2]);
|
||||||
out[A] = in[3];
|
out[A] = in[3];
|
||||||
out += 4; in += 4;
|
out += 4;
|
||||||
|
in += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,10 @@
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
typedef UINT8 pixel[4];
|
typedef UINT8 pixel[4];
|
||||||
|
|
||||||
|
static inline UINT8
|
||||||
static inline UINT8 clip8(int in)
|
clip8(int in) {
|
||||||
{
|
|
||||||
if (in >= 255) {
|
if (in >= 255) {
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
@ -23,11 +21,9 @@ static inline UINT8 clip8(int in)
|
||||||
return (UINT8)in;
|
return (UINT8)in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingUnsharpMask(Imaging imOut, Imaging imIn, float radius, int percent,
|
ImagingUnsharpMask(
|
||||||
int threshold)
|
Imaging imOut, Imaging imIn, float radius, int percent, int threshold) {
|
||||||
{
|
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
Imaging result;
|
Imaging result;
|
||||||
|
|
||||||
|
@ -53,8 +49,7 @@ ImagingUnsharpMask(Imaging imOut, Imaging imIn, float radius, int percent,
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
|
|
||||||
for (y = 0; y < imIn->ysize; y++) {
|
for (y = 0; y < imIn->ysize; y++) {
|
||||||
if (imIn->image8)
|
if (imIn->image8) {
|
||||||
{
|
|
||||||
lineIn8 = imIn->image8[y];
|
lineIn8 = imIn->image8[y];
|
||||||
lineOut8 = imOut->image8[y];
|
lineOut8 = imOut->image8[y];
|
||||||
for (x = 0; x < imIn->xsize; x++) {
|
for (x = 0; x < imIn->xsize; x++) {
|
||||||
|
@ -74,20 +69,24 @@ ImagingUnsharpMask(Imaging imOut, Imaging imIn, float radius, int percent,
|
||||||
for (x = 0; x < imIn->xsize; x++) {
|
for (x = 0; x < imIn->xsize; x++) {
|
||||||
/* compare in/out pixels, apply sharpening */
|
/* compare in/out pixels, apply sharpening */
|
||||||
diff = lineIn[x][0] - lineOut[x][0];
|
diff = lineIn[x][0] - lineOut[x][0];
|
||||||
lineOut[x][0] = abs(diff) > threshold ?
|
lineOut[x][0] = abs(diff) > threshold
|
||||||
clip8(lineIn[x][0] + diff * percent / 100) : lineIn[x][0];
|
? clip8(lineIn[x][0] + diff * percent / 100)
|
||||||
|
: lineIn[x][0];
|
||||||
|
|
||||||
diff = lineIn[x][1] - lineOut[x][1];
|
diff = lineIn[x][1] - lineOut[x][1];
|
||||||
lineOut[x][1] = abs(diff) > threshold ?
|
lineOut[x][1] = abs(diff) > threshold
|
||||||
clip8(lineIn[x][1] + diff * percent / 100) : lineIn[x][1];
|
? clip8(lineIn[x][1] + diff * percent / 100)
|
||||||
|
: lineIn[x][1];
|
||||||
|
|
||||||
diff = lineIn[x][2] - lineOut[x][2];
|
diff = lineIn[x][2] - lineOut[x][2];
|
||||||
lineOut[x][2] = abs(diff) > threshold ?
|
lineOut[x][2] = abs(diff) > threshold
|
||||||
clip8(lineIn[x][2] + diff * percent / 100) : lineIn[x][2];
|
? clip8(lineIn[x][2] + diff * percent / 100)
|
||||||
|
: lineIn[x][2];
|
||||||
|
|
||||||
diff = lineIn[x][3] - lineOut[x][3];
|
diff = lineIn[x][3] - lineOut[x][3];
|
||||||
lineOut[x][3] = abs(diff) > threshold ?
|
lineOut[x][3] = abs(diff) > threshold
|
||||||
clip8(lineIn[x][3] + diff * percent / 100) : lineIn[x][3];
|
? clip8(lineIn[x][3] + diff * percent / 100)
|
||||||
|
: lineIn[x][3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,16 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#define HEX(v) ((v >= '0' && v <= '9') ? v - '0' :\
|
#define HEX(v) \
|
||||||
(v >= 'a' && v <= 'f') ? v - 'a' + 10 :\
|
((v >= '0' && v <= '9') ? v - '0' \
|
||||||
(v >= 'A' && v <= 'F') ? v - 'A' + 10 : 0)
|
: (v >= 'a' && v <= 'f') ? v - 'a' + 10 \
|
||||||
|
: (v >= 'A' && v <= 'F') ? v - 'A' + 10 \
|
||||||
|
: 0)
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
enum { BYTE = 1, SKIP };
|
enum { BYTE = 1, SKIP };
|
||||||
|
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
|
@ -34,9 +34,7 @@ ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (state->state == SKIP) {
|
if (state->state == SKIP) {
|
||||||
|
|
||||||
/* Skip forward until next 'x' */
|
/* Skip forward until next 'x' */
|
||||||
|
|
||||||
while (bytes > 0) {
|
while (bytes > 0) {
|
||||||
|
@ -52,7 +50,6 @@ ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
}
|
}
|
||||||
|
|
||||||
state->state = BYTE;
|
state->state = BYTE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes < 3) {
|
if (bytes < 3) {
|
||||||
|
@ -62,10 +59,8 @@ ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
state->buffer[state->x] = (HEX(ptr[1]) << 4) + HEX(ptr[2]);
|
state->buffer[state->x] = (HEX(ptr[1]) << 4) + HEX(ptr[2]);
|
||||||
|
|
||||||
if (++state->x >= state->bytes) {
|
if (++state->x >= state->bytes) {
|
||||||
|
|
||||||
/* Got a full line, unpack it */
|
/* Got a full line, unpack it */
|
||||||
state->shuffle((UINT8*) im->image[state->y], state->buffer,
|
state->shuffle((UINT8 *)im->image[state->y], state->buffer, state->xsize);
|
||||||
state->xsize);
|
|
||||||
|
|
||||||
state->x = 0;
|
state->x = 0;
|
||||||
|
|
||||||
|
@ -79,7 +74,5 @@ ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
bytes -= 3;
|
bytes -= 3;
|
||||||
|
|
||||||
state->state = SKIP;
|
state->state = SKIP;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,25 +13,20 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
const char *hex = "0123456789abcdef";
|
const char *hex = "0123456789abcdef";
|
||||||
|
|
||||||
UINT8 *ptr = buf;
|
UINT8 *ptr = buf;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
if (!state->state) {
|
if (!state->state) {
|
||||||
|
|
||||||
/* 8 pixels are stored in no more than 6 bytes */
|
/* 8 pixels are stored in no more than 6 bytes */
|
||||||
state->bytes = 6 * (state->xsize + 7) / 8;
|
state->bytes = 6 * (state->xsize + 7) / 8;
|
||||||
|
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes < state->bytes) {
|
if (bytes < state->bytes) {
|
||||||
|
@ -42,16 +37,14 @@ ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
while (bytes >= state->bytes) {
|
while (bytes >= state->bytes) {
|
||||||
|
state->shuffle(
|
||||||
state->shuffle(state->buffer,
|
state->buffer,
|
||||||
(UINT8*) im->image[state->y + state->yoff] +
|
(UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize,
|
||||||
state->xoff * im->pixelsize, state->xsize);
|
state->xsize);
|
||||||
|
|
||||||
if (state->y < state->ysize - 1) {
|
if (state->y < state->ysize - 1) {
|
||||||
|
|
||||||
/* any line but the last */
|
/* any line but the last */
|
||||||
for (n = 0; n < state->xsize; n += 8) {
|
for (n = 0; n < state->xsize; n += 8) {
|
||||||
|
|
||||||
i = state->buffer[n / 8];
|
i = state->buffer[n / 8];
|
||||||
|
|
||||||
*ptr++ = '0';
|
*ptr++ = '0';
|
||||||
|
@ -66,16 +59,13 @@ ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
bytes--;
|
bytes--;
|
||||||
state->count = 0;
|
state->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->y++;
|
state->y++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* last line */
|
/* last line */
|
||||||
for (n = 0; n < state->xsize; n += 8) {
|
for (n = 0; n < state->xsize; n += 8) {
|
||||||
|
|
||||||
i = state->buffer[n / 8];
|
i = state->buffer[n / 8];
|
||||||
|
|
||||||
*ptr++ = '0';
|
*ptr++ = '0';
|
||||||
|
@ -95,7 +85,6 @@ ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes -= 5;
|
bytes -= 5;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->errcode = IMAGING_CODEC_END;
|
state->errcode = IMAGING_CODEC_END;
|
||||||
|
|
|
@ -7,19 +7,15 @@
|
||||||
* Copyright (c) Fredrik Lundh 1996.
|
* Copyright (c) Fredrik Lundh 1996.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
|
|
||||||
/* modes */
|
/* modes */
|
||||||
#define ZIP_PNG 0 /* continuous, filtered image data */
|
#define ZIP_PNG 0 /* continuous, filtered image data */
|
||||||
#define ZIP_PNG_PALETTE 1 /* non-continuous data, disable filtering */
|
#define ZIP_PNG_PALETTE 1 /* non-continuous data, disable filtering */
|
||||||
#define ZIP_TIFF_PREDICTOR 2 /* TIFF, with predictor */
|
#define ZIP_TIFF_PREDICTOR 2 /* TIFF, with predictor */
|
||||||
#define ZIP_TIFF 3 /* TIFF, without predictor */
|
#define ZIP_TIFF 3 /* TIFF, without predictor */
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/* CONFIGURATION */
|
/* CONFIGURATION */
|
||||||
|
|
||||||
/* Codec mode */
|
/* Codec mode */
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
|
@ -30,8 +29,8 @@ static const int ROW_INCREMENT[] = { 8, 8, 8, 4, 4, 2, 2 };
|
||||||
|
|
||||||
/* Get the length in bytes of a scanline in the pass specified,
|
/* Get the length in bytes of a scanline in the pass specified,
|
||||||
* for interlaced images */
|
* for interlaced images */
|
||||||
static int get_row_len(ImagingCodecState state, int pass)
|
static int
|
||||||
{
|
get_row_len(ImagingCodecState state, int pass) {
|
||||||
int row_len = (state->xsize + OFFSET[pass]) / COL_INCREMENT[pass];
|
int row_len = (state->xsize + OFFSET[pass]) / COL_INCREMENT[pass];
|
||||||
return ((row_len * state->bits) + 7) / 8;
|
return ((row_len * state->bits) + 7) / 8;
|
||||||
}
|
}
|
||||||
|
@ -41,8 +40,7 @@ static int get_row_len(ImagingCodecState state, int pass)
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
|
ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
ZIPSTATE *context = (ZIPSTATE *)state->context;
|
ZIPSTATE *context = (ZIPSTATE *)state->context;
|
||||||
int err;
|
int err;
|
||||||
int n;
|
int n;
|
||||||
|
@ -51,7 +49,6 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
int row_len;
|
int row_len;
|
||||||
|
|
||||||
if (!state->state) {
|
if (!state->state) {
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE) {
|
if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE) {
|
||||||
context->prefix = 1; /* PNG */
|
context->prefix = 1; /* PNG */
|
||||||
|
@ -98,7 +95,6 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
|
|
||||||
/* Ready to decode */
|
/* Ready to decode */
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->interlaced) {
|
if (context->interlaced) {
|
||||||
|
@ -113,10 +109,8 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
|
|
||||||
/* Decompress what we've got this far */
|
/* Decompress what we've got this far */
|
||||||
while (context->z_stream.avail_in > 0) {
|
while (context->z_stream.avail_in > 0) {
|
||||||
|
|
||||||
context->z_stream.next_out = state->buffer + context->last_output;
|
context->z_stream.next_out = state->buffer + context->last_output;
|
||||||
context->z_stream.avail_out =
|
context->z_stream.avail_out = row_len + context->prefix - context->last_output;
|
||||||
row_len + context->prefix - context->last_output;
|
|
||||||
|
|
||||||
err = inflate(&context->z_stream, Z_NO_FLUSH);
|
err = inflate(&context->z_stream, Z_NO_FLUSH);
|
||||||
|
|
||||||
|
@ -193,9 +187,9 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
pc = abs(a + b - 2 * c);
|
pc = abs(a + b - 2 * c);
|
||||||
|
|
||||||
/* pick predictor with the shortest distance */
|
/* pick predictor with the shortest distance */
|
||||||
state->buffer[i] +=
|
state->buffer[i] += (pa <= pb && pa <= pc) ? a
|
||||||
(pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
|
: (pb <= pc) ? b
|
||||||
|
: c;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -220,20 +214,22 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
if (state->bits >= 8) {
|
if (state->bits >= 8) {
|
||||||
/* Stuff pixels in their correct location, one by one */
|
/* Stuff pixels in their correct location, one by one */
|
||||||
for (i = 0; i < row_len; i += ((state->bits + 7) / 8)) {
|
for (i = 0; i < row_len; i += ((state->bits + 7) / 8)) {
|
||||||
state->shuffle((UINT8*) im->image[state->y] +
|
state->shuffle(
|
||||||
col * im->pixelsize,
|
(UINT8 *)im->image[state->y] + col * im->pixelsize,
|
||||||
state->buffer + context->prefix + i, 1);
|
state->buffer + context->prefix + i,
|
||||||
|
1);
|
||||||
col += COL_INCREMENT[context->pass];
|
col += COL_INCREMENT[context->pass];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Handle case with more than a pixel in each byte */
|
/* Handle case with more than a pixel in each byte */
|
||||||
int row_bits = ((state->xsize + OFFSET[context->pass])
|
int row_bits = ((state->xsize + OFFSET[context->pass]) /
|
||||||
/ COL_INCREMENT[context->pass]) * state->bits;
|
COL_INCREMENT[context->pass]) *
|
||||||
|
state->bits;
|
||||||
for (i = 0; i < row_bits; i += state->bits) {
|
for (i = 0; i < row_bits; i += state->bits) {
|
||||||
UINT8 byte = *(state->buffer + context->prefix + (i / 8));
|
UINT8 byte = *(state->buffer + context->prefix + (i / 8));
|
||||||
byte <<= (i % 8);
|
byte <<= (i % 8);
|
||||||
state->shuffle((UINT8*) im->image[state->y] +
|
state->shuffle(
|
||||||
col * im->pixelsize, &byte, 1);
|
(UINT8 *)im->image[state->y] + col * im->pixelsize, &byte, 1);
|
||||||
col += COL_INCREMENT[context->pass];
|
col += COL_INCREMENT[context->pass];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +249,8 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
memset(state->buffer, 0, state->bytes + 1);
|
memset(state->buffer, 0, state->bytes + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
state->shuffle(
|
||||||
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
state->xoff * im->pixelsize,
|
state->xoff * im->pixelsize,
|
||||||
state->buffer + context->prefix,
|
state->buffer + context->prefix,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
@ -264,7 +261,6 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
context->last_output = 0;
|
context->last_output = 0;
|
||||||
|
|
||||||
if (state->y >= state->ysize || err == Z_STREAM_END) {
|
if (state->y >= state->ysize || err == Z_STREAM_END) {
|
||||||
|
|
||||||
/* The image and the data should end simultaneously */
|
/* The image and the data should end simultaneously */
|
||||||
/* if (state->y < state->ysize || err != Z_STREAM_END)
|
/* if (state->y < state->ysize || err != Z_STREAM_END)
|
||||||
state->errcode = IMAGING_CODEC_BROKEN; */
|
state->errcode = IMAGING_CODEC_BROKEN; */
|
||||||
|
@ -273,22 +269,19 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||||
context->previous = NULL;
|
context->previous = NULL;
|
||||||
inflateEnd(&context->z_stream);
|
inflateEnd(&context->z_stream);
|
||||||
return -1; /* end of file (errcode=0) */
|
return -1; /* end of file (errcode=0) */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Swap buffer pointers */
|
/* Swap buffer pointers */
|
||||||
ptr = state->buffer;
|
ptr = state->buffer;
|
||||||
state->buffer = context->previous;
|
state->buffer = context->previous;
|
||||||
context->previous = ptr;
|
context->previous = ptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes; /* consumed all of it */
|
return bytes; /* consumed all of it */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
int ImagingZipDecodeCleanup(ImagingCodecState state){
|
ImagingZipDecodeCleanup(ImagingCodecState state) {
|
||||||
/* called to free the decompression engine when the decode terminates
|
/* called to free the decompression engine when the decode terminates
|
||||||
due to a corrupt or truncated image
|
due to a corrupt or truncated image
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
|
@ -22,8 +21,7 @@
|
||||||
#include "ZipCodecs.h"
|
#include "ZipCodecs.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
||||||
{
|
|
||||||
ZIPSTATE *context = (ZIPSTATE *)state->context;
|
ZIPSTATE *context = (ZIPSTATE *)state->context;
|
||||||
int err;
|
int err;
|
||||||
int compress_level, compress_type;
|
int compress_level, compress_type;
|
||||||
|
@ -32,7 +30,6 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
|
|
||||||
if (!state->state) {
|
if (!state->state) {
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
|
|
||||||
/* Valid modes are ZIP_PNG, ZIP_PNG_PALETTE, and ZIP_TIFF */
|
/* Valid modes are ZIP_PNG, ZIP_PNG_PALETTE, and ZIP_TIFF */
|
||||||
|
@ -53,8 +50,8 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
context->up = (UINT8 *)malloc(state->bytes + 1);
|
context->up = (UINT8 *)malloc(state->bytes + 1);
|
||||||
context->average = (UINT8 *)malloc(state->bytes + 1);
|
context->average = (UINT8 *)malloc(state->bytes + 1);
|
||||||
context->paeth = (UINT8 *)malloc(state->bytes + 1);
|
context->paeth = (UINT8 *)malloc(state->bytes + 1);
|
||||||
if (!state->buffer || !context->previous || !context->prior ||
|
if (!state->buffer || !context->previous || !context->prior || !context->up ||
|
||||||
!context->up || !context->average || !context->paeth) {
|
!context->average || !context->paeth) {
|
||||||
free(context->paeth);
|
free(context->paeth);
|
||||||
free(context->average);
|
free(context->average);
|
||||||
free(context->up);
|
free(context->up);
|
||||||
|
@ -81,23 +78,25 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
context->z_stream.next_in = 0;
|
context->z_stream.next_in = 0;
|
||||||
context->z_stream.avail_in = 0;
|
context->z_stream.avail_in = 0;
|
||||||
|
|
||||||
compress_level = (context->optimize) ? Z_BEST_COMPRESSION
|
compress_level =
|
||||||
: context->compress_level;
|
(context->optimize) ? Z_BEST_COMPRESSION : context->compress_level;
|
||||||
|
|
||||||
if (context->compress_type == -1) {
|
if (context->compress_type == -1) {
|
||||||
compress_type = (context->mode == ZIP_PNG) ? Z_FILTERED
|
compress_type =
|
||||||
: Z_DEFAULT_STRATEGY;
|
(context->mode == ZIP_PNG) ? Z_FILTERED : Z_DEFAULT_STRATEGY;
|
||||||
} else {
|
} else {
|
||||||
compress_type = context->compress_type;
|
compress_type = context->compress_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = deflateInit2(&context->z_stream,
|
err = deflateInit2(
|
||||||
|
&context->z_stream,
|
||||||
/* compression level */
|
/* compression level */
|
||||||
compress_level,
|
compress_level,
|
||||||
/* compression method */
|
/* compression method */
|
||||||
Z_DEFLATED,
|
Z_DEFLATED,
|
||||||
/* compression memory resources */
|
/* compression memory resources */
|
||||||
15, 9,
|
15,
|
||||||
|
9,
|
||||||
/* compression strategy (image data are filtered)*/
|
/* compression strategy (image data are filtered)*/
|
||||||
compress_type);
|
compress_type);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -106,7 +105,9 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->dictionary && context->dictionary_size > 0) {
|
if (context->dictionary && context->dictionary_size > 0) {
|
||||||
err = deflateSetDictionary(&context->z_stream, (unsigned char *)context->dictionary,
|
err = deflateSetDictionary(
|
||||||
|
&context->z_stream,
|
||||||
|
(unsigned char *)context->dictionary,
|
||||||
context->dictionary_size);
|
context->dictionary_size);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
state->errcode = IMAGING_CODEC_CONFIG;
|
state->errcode = IMAGING_CODEC_CONFIG;
|
||||||
|
@ -116,7 +117,6 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
|
|
||||||
/* Ready to decode */
|
/* Ready to decode */
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup the destination buffer */
|
/* Setup the destination buffer */
|
||||||
|
@ -147,23 +147,20 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
|
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
switch (state->state) {
|
switch (state->state) {
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
|
||||||
/* Compress image data */
|
/* Compress image data */
|
||||||
while (context->z_stream.avail_out > 0) {
|
while (context->z_stream.avail_out > 0) {
|
||||||
|
|
||||||
if (state->y >= state->ysize) {
|
if (state->y >= state->ysize) {
|
||||||
/* End of image; now flush compressor buffers */
|
/* End of image; now flush compressor buffers */
|
||||||
state->state = 2;
|
state->state = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stuff image data into the compressor */
|
/* Stuff image data into the compressor */
|
||||||
state->shuffle(state->buffer+1,
|
state->shuffle(
|
||||||
|
state->buffer + 1,
|
||||||
(UINT8 *)im->image[state->y + state->yoff] +
|
(UINT8 *)im->image[state->y + state->yoff] +
|
||||||
state->xoff * im->pixelsize,
|
state->xoff * im->pixelsize,
|
||||||
state->xsize);
|
state->xsize);
|
||||||
|
@ -173,7 +170,6 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
context->output = state->buffer;
|
context->output = state->buffer;
|
||||||
|
|
||||||
if (context->mode == ZIP_PNG) {
|
if (context->mode == ZIP_PNG) {
|
||||||
|
|
||||||
/* Filter the image data. For each line, select
|
/* Filter the image data. For each line, select
|
||||||
the filter that gives the least total distance
|
the filter that gives the least total distance
|
||||||
from zero for the filtered data (taken from
|
from zero for the filtered data (taken from
|
||||||
|
@ -228,7 +224,8 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
s += (v < 128) ? v : 256 - v;
|
s += (v < 128) ? v : 256 - v;
|
||||||
}
|
}
|
||||||
for (; i <= state->bytes; i++) {
|
for (; i <= state->bytes; i++) {
|
||||||
UINT8 v = state->buffer[i] -
|
UINT8 v =
|
||||||
|
state->buffer[i] -
|
||||||
(state->buffer[i - bpp] + context->previous[i]) / 2;
|
(state->buffer[i - bpp] + context->previous[i]) / 2;
|
||||||
context->average[i] = v;
|
context->average[i] = v;
|
||||||
s += (v < 128) ? v : 256 - v;
|
s += (v < 128) ? v : 256 - v;
|
||||||
|
@ -262,9 +259,9 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
pc = abs(a + b - 2 * c);
|
pc = abs(a + b - 2 * c);
|
||||||
|
|
||||||
/* pick predictor with the shortest distance */
|
/* pick predictor with the shortest distance */
|
||||||
v = state->buffer[i] -
|
v = state->buffer[i] - ((pa <= pb && pa <= pc) ? a
|
||||||
((pa <= pb && pa <= pc) ? a :
|
: (pb <= pc) ? b
|
||||||
(pb <= pc) ? b : c);
|
: c);
|
||||||
context->paeth[i] = v;
|
context->paeth[i] = v;
|
||||||
s += (v < 128) ? v : 256 - v;
|
s += (v < 128) ? v : 256 - v;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +301,6 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
ptr = state->buffer;
|
ptr = state->buffer;
|
||||||
state->buffer = context->previous;
|
state->buffer = context->previous;
|
||||||
context->previous = ptr;
|
context->previous = ptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->z_stream.avail_out == 0) {
|
if (context->z_stream.avail_out == 0) {
|
||||||
|
@ -316,11 +312,9 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
/* End of image data; flush compressor buffers */
|
/* End of image data; flush compressor buffers */
|
||||||
|
|
||||||
while (context->z_stream.avail_out > 0) {
|
while (context->z_stream.avail_out > 0) {
|
||||||
|
|
||||||
err = deflate(&context->z_stream, Z_FINISH);
|
err = deflate(&context->z_stream, Z_FINISH);
|
||||||
|
|
||||||
if (err == Z_STREAM_END) {
|
if (err == Z_STREAM_END) {
|
||||||
|
|
||||||
free(context->paeth);
|
free(context->paeth);
|
||||||
free(context->average);
|
free(context->average);
|
||||||
free(context->up);
|
free(context->up);
|
||||||
|
@ -337,13 +331,10 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
if (context->z_stream.avail_out == 0) {
|
if (context->z_stream.avail_out == 0) {
|
||||||
break; /* Buffer full */
|
break; /* Buffer full */
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
return bytes - context->z_stream.avail_out;
|
return bytes - context->z_stream.avail_out;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Should never ever arrive here... */
|
/* Should never ever arrive here... */
|
||||||
|
@ -368,11 +359,8 @@ ImagingZipEncodeCleanup(ImagingCodecState state) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
ImagingZipVersion(void)
|
ImagingZipVersion(void) {
|
||||||
{
|
|
||||||
return zlibVersion();
|
return zlibVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
Py_ssize_t
|
Py_ssize_t
|
||||||
_imaging_read_pyFd(PyObject *fd, char* dest, Py_ssize_t bytes)
|
_imaging_read_pyFd(PyObject *fd, char *dest, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
/* dest should be a buffer bytes long, returns length of read
|
/* dest should be a buffer bytes long, returns length of read
|
||||||
-1 on error */
|
-1 on error */
|
||||||
|
|
||||||
|
@ -32,13 +30,10 @@ _imaging_read_pyFd(PyObject *fd, char* dest, Py_ssize_t bytes)
|
||||||
err:
|
err:
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t
|
Py_ssize_t
|
||||||
_imaging_write_pyFd(PyObject *fd, char* src, Py_ssize_t bytes)
|
_imaging_write_pyFd(PyObject *fd, char *src, Py_ssize_t bytes) {
|
||||||
{
|
|
||||||
|
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
PyObject *byteObj;
|
PyObject *byteObj;
|
||||||
|
|
||||||
|
@ -49,24 +44,20 @@ _imaging_write_pyFd(PyObject *fd, char* src, Py_ssize_t bytes)
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_imaging_seek_pyFd(PyObject *fd, Py_ssize_t offset, int whence)
|
_imaging_seek_pyFd(PyObject *fd, Py_ssize_t offset, int whence) {
|
||||||
{
|
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
|
||||||
result = PyObject_CallMethod(fd, "seek", "ni", offset, whence);
|
result = PyObject_CallMethod(fd, "seek", "ni", offset, whence);
|
||||||
|
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t
|
Py_ssize_t
|
||||||
_imaging_tell_pyFd(PyObject *fd)
|
_imaging_tell_pyFd(PyObject *fd) {
|
||||||
{
|
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
Py_ssize_t location;
|
Py_ssize_t location;
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,7 @@ typedef struct _raqm raqm_t;
|
||||||
*
|
*
|
||||||
* Since: 0.1
|
* Since: 0.1
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
RAQM_DIRECTION_DEFAULT,
|
RAQM_DIRECTION_DEFAULT,
|
||||||
RAQM_DIRECTION_RTL,
|
RAQM_DIRECTION_RTL,
|
||||||
RAQM_DIRECTION_LTR,
|
RAQM_DIRECTION_LTR,
|
||||||
|
@ -106,7 +105,6 @@ typedef struct raqm_glyph_t_01 {
|
||||||
uint32_t cluster;
|
uint32_t cluster;
|
||||||
} raqm_glyph_t_01;
|
} raqm_glyph_t_01;
|
||||||
|
|
||||||
|
|
||||||
raqm_t *
|
raqm_t *
|
||||||
raqm_create(void);
|
raqm_create(void);
|
||||||
|
|
||||||
|
@ -117,62 +115,40 @@ void
|
||||||
raqm_destroy(raqm_t *rq);
|
raqm_destroy(raqm_t *rq);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_text (raqm_t *rq,
|
raqm_set_text(raqm_t *rq, const uint32_t *text, size_t len);
|
||||||
const uint32_t *text,
|
|
||||||
size_t len);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_text_utf8 (raqm_t *rq,
|
raqm_set_text_utf8(raqm_t *rq, const char *text, size_t len);
|
||||||
const char *text,
|
|
||||||
size_t len);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_par_direction (raqm_t *rq,
|
raqm_set_par_direction(raqm_t *rq, raqm_direction_t dir);
|
||||||
raqm_direction_t dir);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_language (raqm_t *rq,
|
raqm_set_language(raqm_t *rq, const char *lang, size_t start, size_t len);
|
||||||
const char *lang,
|
|
||||||
size_t start,
|
|
||||||
size_t len);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_add_font_feature (raqm_t *rq,
|
raqm_add_font_feature(raqm_t *rq, const char *feature, int len);
|
||||||
const char *feature,
|
|
||||||
int len);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_freetype_face (raqm_t *rq,
|
raqm_set_freetype_face(raqm_t *rq, FT_Face face);
|
||||||
FT_Face face);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_freetype_face_range (raqm_t *rq,
|
raqm_set_freetype_face_range(raqm_t *rq, FT_Face face, size_t start, size_t len);
|
||||||
FT_Face face,
|
|
||||||
size_t start,
|
|
||||||
size_t len);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_freetype_load_flags (raqm_t *rq,
|
raqm_set_freetype_load_flags(raqm_t *rq, int flags);
|
||||||
int flags);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_layout(raqm_t *rq);
|
raqm_layout(raqm_t *rq);
|
||||||
|
|
||||||
raqm_glyph_t *
|
raqm_glyph_t *
|
||||||
raqm_get_glyphs (raqm_t *rq,
|
raqm_get_glyphs(raqm_t *rq, size_t *length);
|
||||||
size_t *length);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_index_to_position (raqm_t *rq,
|
raqm_index_to_position(raqm_t *rq, size_t *index, int *x, int *y);
|
||||||
size_t *index,
|
|
||||||
int *x,
|
|
||||||
int *y);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_position_to_index (raqm_t *rq,
|
raqm_position_to_index(raqm_t *rq, int x, int y, size_t *index);
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
size_t *index);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
76
src/map.c
76
src/map.c
|
@ -23,15 +23,16 @@
|
||||||
#include "libImaging/Imaging.h"
|
#include "libImaging/Imaging.h"
|
||||||
|
|
||||||
/* compatibility wrappers (defined in _imaging.c) */
|
/* compatibility wrappers (defined in _imaging.c) */
|
||||||
extern int PyImaging_CheckBuffer(PyObject* buffer);
|
extern int
|
||||||
extern int PyImaging_GetBuffer(PyObject* buffer, Py_buffer *view);
|
PyImaging_CheckBuffer(PyObject *buffer);
|
||||||
|
extern int
|
||||||
|
PyImaging_GetBuffer(PyObject *buffer, Py_buffer *view);
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Standard mapper */
|
/* Standard mapper */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD char *base;
|
||||||
char* base;
|
|
||||||
int size;
|
int size;
|
||||||
int offset;
|
int offset;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -43,8 +44,7 @@ typedef struct {
|
||||||
static PyTypeObject ImagingMapperType;
|
static PyTypeObject ImagingMapperType;
|
||||||
|
|
||||||
ImagingMapperObject *
|
ImagingMapperObject *
|
||||||
PyImaging_MapperNew(const char* filename, int readonly)
|
PyImaging_MapperNew(const char *filename, int readonly) {
|
||||||
{
|
|
||||||
ImagingMapperObject *mapper;
|
ImagingMapperObject *mapper;
|
||||||
|
|
||||||
if (PyType_Ready(&ImagingMapperType) < 0) {
|
if (PyType_Ready(&ImagingMapperType) < 0) {
|
||||||
|
@ -68,7 +68,8 @@ PyImaging_MapperNew(const char* filename, int readonly)
|
||||||
filename,
|
filename,
|
||||||
GENERIC_READ,
|
GENERIC_READ,
|
||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
NULL, OPEN_EXISTING,
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL);
|
NULL);
|
||||||
if (mapper->hFile == (HANDLE)-1) {
|
if (mapper->hFile == (HANDLE)-1) {
|
||||||
|
@ -77,10 +78,7 @@ PyImaging_MapperNew(const char* filename, int readonly)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper->hMap = CreateFileMapping(
|
mapper->hMap = CreateFileMapping(mapper->hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||||
mapper->hFile, NULL,
|
|
||||||
PAGE_READONLY,
|
|
||||||
0, 0, NULL);
|
|
||||||
if (mapper->hMap == (HANDLE)-1) {
|
if (mapper->hMap == (HANDLE)-1) {
|
||||||
CloseHandle(mapper->hFile);
|
CloseHandle(mapper->hFile);
|
||||||
PyErr_SetString(PyExc_OSError, "cannot map file");
|
PyErr_SetString(PyExc_OSError, "cannot map file");
|
||||||
|
@ -88,10 +86,7 @@ PyImaging_MapperNew(const char* filename, int readonly)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper->base = (char*) MapViewOfFile(
|
mapper->base = (char *)MapViewOfFile(mapper->hMap, FILE_MAP_READ, 0, 0, 0);
|
||||||
mapper->hMap,
|
|
||||||
FILE_MAP_READ,
|
|
||||||
0, 0, 0);
|
|
||||||
|
|
||||||
mapper->size = GetFileSize(mapper->hFile, 0);
|
mapper->size = GetFileSize(mapper->hFile, 0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -100,8 +95,7 @@ PyImaging_MapperNew(const char* filename, int readonly)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mapping_dealloc(ImagingMapperObject* mapper)
|
mapping_dealloc(ImagingMapperObject *mapper) {
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (mapper->base != 0) {
|
if (mapper->base != 0) {
|
||||||
UnmapViewOfFile(mapper->base);
|
UnmapViewOfFile(mapper->base);
|
||||||
|
@ -122,8 +116,7 @@ mapping_dealloc(ImagingMapperObject* mapper)
|
||||||
/* standard file operations */
|
/* standard file operations */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mapping_read(ImagingMapperObject* mapper, PyObject* args)
|
mapping_read(ImagingMapperObject *mapper, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *buf;
|
PyObject *buf;
|
||||||
|
|
||||||
int size = -1;
|
int size = -1;
|
||||||
|
@ -153,8 +146,7 @@ mapping_read(ImagingMapperObject* mapper, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mapping_seek(ImagingMapperObject* mapper, PyObject* args)
|
mapping_seek(ImagingMapperObject *mapper, PyObject *args) {
|
||||||
{
|
|
||||||
int offset;
|
int offset;
|
||||||
int whence = 0;
|
int whence = 0;
|
||||||
if (!PyArg_ParseTuple(args, "i|i", &offset, &whence)) {
|
if (!PyArg_ParseTuple(args, "i|i", &offset, &whence)) {
|
||||||
|
@ -183,17 +175,16 @@ mapping_seek(ImagingMapperObject* mapper, PyObject* args)
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* map entire image */
|
/* map entire image */
|
||||||
|
|
||||||
extern PyObject*PyImagingNew(Imaging im);
|
extern PyObject *
|
||||||
|
PyImagingNew(Imaging im);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ImagingDestroyMap(Imaging im)
|
ImagingDestroyMap(Imaging im) {
|
||||||
{
|
|
||||||
return; /* nothing to do! */
|
return; /* nothing to do! */
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mapping_readimage(ImagingMapperObject* mapper, PyObject* args)
|
mapping_readimage(ImagingMapperObject *mapper, PyObject *args) {
|
||||||
{
|
|
||||||
int y, size;
|
int y, size;
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
|
||||||
|
@ -202,8 +193,8 @@ mapping_readimage(ImagingMapperObject* mapper, PyObject* args)
|
||||||
int ysize;
|
int ysize;
|
||||||
int stride;
|
int stride;
|
||||||
int orientation;
|
int orientation;
|
||||||
if (!PyArg_ParseTuple(args, "s(ii)ii", &mode, &xsize, &ysize,
|
if (!PyArg_ParseTuple(
|
||||||
&stride, &orientation)) {
|
args, "s(ii)ii", &mode, &xsize, &ysize, &stride, &orientation)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,8 +249,7 @@ static struct PyMethodDef methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyTypeObject ImagingMapperType = {
|
static PyTypeObject ImagingMapperType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "ImagingMapper", /*tp_name*/
|
||||||
"ImagingMapper", /*tp_name*/
|
|
||||||
sizeof(ImagingMapperObject), /*tp_size*/
|
sizeof(ImagingMapperObject), /*tp_size*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
/* methods */
|
/* methods */
|
||||||
|
@ -292,8 +282,7 @@ static PyTypeObject ImagingMapperType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_Mapper(PyObject* self, PyObject* args)
|
PyImaging_Mapper(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
char *filename;
|
char *filename;
|
||||||
if (!PyArg_ParseTuple(args, "s", &filename)) {
|
if (!PyArg_ParseTuple(args, "s", &filename)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -312,8 +301,7 @@ typedef struct ImagingBufferInstance {
|
||||||
} ImagingBufferInstance;
|
} ImagingBufferInstance;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mapping_destroy_buffer(Imaging im)
|
mapping_destroy_buffer(Imaging im) {
|
||||||
{
|
|
||||||
ImagingBufferInstance *buffer = (ImagingBufferInstance *)im;
|
ImagingBufferInstance *buffer = (ImagingBufferInstance *)im;
|
||||||
|
|
||||||
PyBuffer_Release(&buffer->view);
|
PyBuffer_Release(&buffer->view);
|
||||||
|
@ -321,8 +309,7 @@ mapping_destroy_buffer(Imaging im)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImaging_MapBuffer(PyObject* self, PyObject* args)
|
PyImaging_MapBuffer(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
Py_ssize_t y, size;
|
Py_ssize_t y, size;
|
||||||
Imaging im;
|
Imaging im;
|
||||||
|
|
||||||
|
@ -335,8 +322,17 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
|
||||||
int stride;
|
int stride;
|
||||||
int ystep;
|
int ystep;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O(ii)sn(sii)", &target, &xsize, &ysize,
|
if (!PyArg_ParseTuple(
|
||||||
&codec, &offset, &mode, &stride, &ystep)) {
|
args,
|
||||||
|
"O(ii)sn(sii)",
|
||||||
|
&target,
|
||||||
|
&xsize,
|
||||||
|
&ysize,
|
||||||
|
&codec,
|
||||||
|
&offset,
|
||||||
|
&mode,
|
||||||
|
&stride,
|
||||||
|
&ystep)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,8 +379,7 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
im = ImagingNewPrologueSubtype(
|
im = ImagingNewPrologueSubtype(mode, xsize, ysize, sizeof(ImagingBufferInstance));
|
||||||
mode, xsize, ysize, sizeof(ImagingBufferInstance));
|
|
||||||
if (!im) {
|
if (!im) {
|
||||||
PyBuffer_Release(&view);
|
PyBuffer_Release(&view);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -409,4 +404,3 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
return PyImagingNew(im);
|
return PyImagingNew(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,11 @@
|
||||||
|
|
||||||
#include "libImaging/Imaging.h"
|
#include "libImaging/Imaging.h"
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Class */
|
/* Class */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD ImagingOutline outline;
|
||||||
ImagingOutline outline;
|
|
||||||
} OutlineObject;
|
} OutlineObject;
|
||||||
|
|
||||||
static PyTypeObject OutlineType;
|
static PyTypeObject OutlineType;
|
||||||
|
@ -35,8 +33,7 @@ static PyTypeObject OutlineType;
|
||||||
#define PyOutline_Check(op) (Py_TYPE(op) == &OutlineType)
|
#define PyOutline_Check(op) (Py_TYPE(op) == &OutlineType)
|
||||||
|
|
||||||
static OutlineObject *
|
static OutlineObject *
|
||||||
_outline_new(void)
|
_outline_new(void) {
|
||||||
{
|
|
||||||
OutlineObject *self;
|
OutlineObject *self;
|
||||||
|
|
||||||
if (PyType_Ready(&OutlineType) < 0) {
|
if (PyType_Ready(&OutlineType) < 0) {
|
||||||
|
@ -54,15 +51,13 @@ _outline_new(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_outline_dealloc(OutlineObject* self)
|
_outline_dealloc(OutlineObject *self) {
|
||||||
{
|
|
||||||
ImagingOutlineDelete(self->outline);
|
ImagingOutlineDelete(self->outline);
|
||||||
PyObject_Del(self);
|
PyObject_Del(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagingOutline
|
ImagingOutline
|
||||||
PyOutline_AsOutline(PyObject* outline)
|
PyOutline_AsOutline(PyObject *outline) {
|
||||||
{
|
|
||||||
if (PyOutline_Check(outline)) {
|
if (PyOutline_Check(outline)) {
|
||||||
return ((OutlineObject *)outline)->outline;
|
return ((OutlineObject *)outline)->outline;
|
||||||
}
|
}
|
||||||
|
@ -70,13 +65,11 @@ PyOutline_AsOutline(PyObject* outline)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Factories */
|
/* Factories */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyOutline_Create(PyObject* self, PyObject* args)
|
PyOutline_Create(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
if (!PyArg_ParseTuple(args, ":outline")) {
|
if (!PyArg_ParseTuple(args, ":outline")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -84,13 +77,11 @@ PyOutline_Create(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)_outline_new();
|
return (PyObject *)_outline_new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Methods */
|
/* Methods */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_outline_move(OutlineObject* self, PyObject* args)
|
_outline_move(OutlineObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
float x0, y0;
|
float x0, y0;
|
||||||
if (!PyArg_ParseTuple(args, "ff", &x0, &y0)) {
|
if (!PyArg_ParseTuple(args, "ff", &x0, &y0)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -103,8 +94,7 @@ _outline_move(OutlineObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_outline_line(OutlineObject* self, PyObject* args)
|
_outline_line(OutlineObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
float x1, y1;
|
float x1, y1;
|
||||||
if (!PyArg_ParseTuple(args, "ff", &x1, &y1)) {
|
if (!PyArg_ParseTuple(args, "ff", &x1, &y1)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -117,8 +107,7 @@ _outline_line(OutlineObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_outline_curve(OutlineObject* self, PyObject* args)
|
_outline_curve(OutlineObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
float x1, y1, x2, y2, x3, y3;
|
float x1, y1, x2, y2, x3, y3;
|
||||||
if (!PyArg_ParseTuple(args, "ffffff", &x1, &y1, &x2, &y2, &x3, &y3)) {
|
if (!PyArg_ParseTuple(args, "ffffff", &x1, &y1, &x2, &y2, &x3, &y3)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -131,8 +120,7 @@ _outline_curve(OutlineObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_outline_close(OutlineObject* self, PyObject* args)
|
_outline_close(OutlineObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
if (!PyArg_ParseTuple(args, ":close")) {
|
if (!PyArg_ParseTuple(args, ":close")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -144,8 +132,7 @@ _outline_close(OutlineObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_outline_transform(OutlineObject* self, PyObject* args)
|
_outline_transform(OutlineObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
double a[6];
|
double a[6];
|
||||||
if (!PyArg_ParseTuple(args, "(dddddd)", a + 0, a + 1, a + 2, a + 3, a + 4, a + 5)) {
|
if (!PyArg_ParseTuple(args, "(dddddd)", a + 0, a + 1, a + 2, a + 3, a + 4, a + 5)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -167,8 +154,7 @@ static struct PyMethodDef _outline_methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyTypeObject OutlineType = {
|
static PyTypeObject OutlineType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "Outline", /*tp_name*/
|
||||||
"Outline", /*tp_name*/
|
|
||||||
sizeof(OutlineObject), /*tp_size*/
|
sizeof(OutlineObject), /*tp_size*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
/* methods */
|
/* methods */
|
||||||
|
|
102
src/path.c
102
src/path.c
|
@ -25,23 +25,23 @@
|
||||||
* See the README file for information on usage and redistribution.
|
* See the README file for information on usage and redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "libImaging/Imaging.h"
|
#include "libImaging/Imaging.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
/* compatibility wrappers (defined in _imaging.c) */
|
/* compatibility wrappers (defined in _imaging.c) */
|
||||||
extern int PyImaging_CheckBuffer(PyObject* buffer);
|
extern int
|
||||||
extern int PyImaging_GetBuffer(PyObject* buffer, Py_buffer *view);
|
PyImaging_CheckBuffer(PyObject *buffer);
|
||||||
|
extern int
|
||||||
|
PyImaging_GetBuffer(PyObject *buffer, Py_buffer *view);
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Class */
|
/* Class */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD Py_ssize_t count;
|
||||||
Py_ssize_t count;
|
|
||||||
double *xy;
|
double *xy;
|
||||||
int index; /* temporary use, e.g. in decimate */
|
int index; /* temporary use, e.g. in decimate */
|
||||||
} PyPathObject;
|
} PyPathObject;
|
||||||
|
@ -49,8 +49,7 @@ typedef struct {
|
||||||
static PyTypeObject PyPathType;
|
static PyTypeObject PyPathType;
|
||||||
|
|
||||||
static double *
|
static double *
|
||||||
alloc_array(Py_ssize_t count)
|
alloc_array(Py_ssize_t count) {
|
||||||
{
|
|
||||||
double *xy;
|
double *xy;
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
return ImagingError_MemoryError();
|
return ImagingError_MemoryError();
|
||||||
|
@ -66,8 +65,7 @@ alloc_array(Py_ssize_t count)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyPathObject *
|
static PyPathObject *
|
||||||
path_new(Py_ssize_t count, double* xy, int duplicate)
|
path_new(Py_ssize_t count, double *xy, int duplicate) {
|
||||||
{
|
|
||||||
PyPathObject *path;
|
PyPathObject *path;
|
||||||
|
|
||||||
if (duplicate) {
|
if (duplicate) {
|
||||||
|
@ -98,8 +96,7 @@ path_new(Py_ssize_t count, double* xy, int duplicate)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
path_dealloc(PyPathObject* path)
|
path_dealloc(PyPathObject *path) {
|
||||||
{
|
|
||||||
free(path->xy);
|
free(path->xy);
|
||||||
PyObject_Del(path);
|
PyObject_Del(path);
|
||||||
}
|
}
|
||||||
|
@ -111,8 +108,7 @@ path_dealloc(PyPathObject* path)
|
||||||
#define PyPath_Check(op) (Py_TYPE(op) == &PyPathType)
|
#define PyPath_Check(op) (Py_TYPE(op) == &PyPathType)
|
||||||
|
|
||||||
Py_ssize_t
|
Py_ssize_t
|
||||||
PyPath_Flatten(PyObject* data, double **pxy)
|
PyPath_Flatten(PyObject *data, double **pxy) {
|
||||||
{
|
|
||||||
Py_ssize_t i, j, n;
|
Py_ssize_t i, j, n;
|
||||||
double *xy;
|
double *xy;
|
||||||
|
|
||||||
|
@ -209,8 +205,7 @@ PyPath_Flatten(PyObject* data, double **pxy)
|
||||||
PyObject *op = PySequence_GetItem(data, i);
|
PyObject *op = PySequence_GetItem(data, i);
|
||||||
if (!op) {
|
if (!op) {
|
||||||
/* treat IndexError as end of sequence */
|
/* treat IndexError as end of sequence */
|
||||||
if (PyErr_Occurred() &&
|
if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_IndexError)) {
|
||||||
PyErr_ExceptionMatches(PyExc_IndexError)) {
|
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -246,20 +241,17 @@ PyPath_Flatten(PyObject* data, double **pxy)
|
||||||
return j / 2;
|
return j / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Factories */
|
/* Factories */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyPath_Create(PyObject* self, PyObject* args)
|
PyPath_Create(PyObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *data;
|
PyObject *data;
|
||||||
Py_ssize_t count;
|
Py_ssize_t count;
|
||||||
double *xy;
|
double *xy;
|
||||||
|
|
||||||
if (PyArg_ParseTuple(args, "n:Path", &count)) {
|
if (PyArg_ParseTuple(args, "n:Path", &count)) {
|
||||||
|
|
||||||
/* number of vertices */
|
/* number of vertices */
|
||||||
xy = alloc_array(count);
|
xy = alloc_array(count);
|
||||||
if (!xy) {
|
if (!xy) {
|
||||||
|
@ -267,7 +259,6 @@ PyPath_Create(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* sequence or other path */
|
/* sequence or other path */
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
if (!PyArg_ParseTuple(args, "O", &data)) {
|
if (!PyArg_ParseTuple(args, "O", &data)) {
|
||||||
|
@ -283,14 +274,12 @@ PyPath_Create(PyObject* self, PyObject* args)
|
||||||
return (PyObject *)path_new(count, xy, 0);
|
return (PyObject *)path_new(count, xy, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Methods */
|
/* Methods */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_compact(PyPathObject* self, PyObject* args)
|
path_compact(PyPathObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
/* Simple-minded method to shorten path. A point is removed if
|
/* Simple-minded method to shorten path. A point is removed if
|
||||||
the city block distance to the previous point is less than the
|
the city block distance to the previous point is less than the
|
||||||
given distance */
|
given distance */
|
||||||
|
@ -307,7 +296,8 @@ path_compact(PyPathObject* self, PyObject* args)
|
||||||
|
|
||||||
/* remove bogus vertices */
|
/* remove bogus vertices */
|
||||||
for (i = j = 1; i < self->count; i++) {
|
for (i = j = 1; i < self->count; i++) {
|
||||||
if (fabs(xy[j+j-2]-xy[i+i]) + fabs(xy[j+j-1]-xy[i+i+1]) >= cityblock) {
|
if (fabs(xy[j + j - 2] - xy[i + i]) + fabs(xy[j + j - 1] - xy[i + i + 1]) >=
|
||||||
|
cityblock) {
|
||||||
xy[j + j] = xy[i + i];
|
xy[j + j] = xy[i + i];
|
||||||
xy[j + j + 1] = xy[i + i + 1];
|
xy[j + j + 1] = xy[i + i + 1];
|
||||||
j++;
|
j++;
|
||||||
|
@ -325,8 +315,7 @@ path_compact(PyPathObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_getbbox(PyPathObject* self, PyObject* args)
|
path_getbbox(PyPathObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
/* Find bounding box */
|
/* Find bounding box */
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
double *xy;
|
double *xy;
|
||||||
|
@ -360,8 +349,7 @@ path_getbbox(PyPathObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_getitem(PyPathObject* self, Py_ssize_t i)
|
path_getitem(PyPathObject *self, Py_ssize_t i) {
|
||||||
{
|
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
i = self->count + i;
|
i = self->count + i;
|
||||||
}
|
}
|
||||||
|
@ -374,8 +362,7 @@ path_getitem(PyPathObject* self, Py_ssize_t i)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_getslice(PyPathObject* self, Py_ssize_t ilow, Py_ssize_t ihigh)
|
path_getslice(PyPathObject *self, Py_ssize_t ilow, Py_ssize_t ihigh) {
|
||||||
{
|
|
||||||
/* adjust arguments */
|
/* adjust arguments */
|
||||||
if (ilow < 0) {
|
if (ilow < 0) {
|
||||||
ilow = 0;
|
ilow = 0;
|
||||||
|
@ -395,14 +382,12 @@ path_getslice(PyPathObject* self, Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Py_ssize_t
|
static Py_ssize_t
|
||||||
path_len(PyPathObject* self)
|
path_len(PyPathObject *self) {
|
||||||
{
|
|
||||||
return self->count;
|
return self->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_map(PyPathObject* self, PyObject* args)
|
path_map(PyPathObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
/* Map coordinate set through function */
|
/* Map coordinate set through function */
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
double *xy;
|
double *xy;
|
||||||
|
@ -433,19 +418,16 @@ path_map(PyPathObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
path_setitem(PyPathObject* self, Py_ssize_t i, PyObject* op)
|
path_setitem(PyPathObject *self, Py_ssize_t i, PyObject *op) {
|
||||||
{
|
|
||||||
double *xy;
|
double *xy;
|
||||||
|
|
||||||
if (i < 0 || i >= self->count) {
|
if (i < 0 || i >= self->count) {
|
||||||
PyErr_SetString(PyExc_IndexError,
|
PyErr_SetString(PyExc_IndexError, "path assignment index out of range");
|
||||||
"path assignment index out of range");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == NULL) {
|
if (op == NULL) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError, "cannot delete from path");
|
||||||
"cannot delete from path");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,8 +441,7 @@ path_setitem(PyPathObject* self, Py_ssize_t i, PyObject* op)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_tolist(PyPathObject* self, PyObject* args)
|
path_tolist(PyPathObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *list;
|
PyObject *list;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
|
@ -499,8 +480,7 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_transform(PyPathObject* self, PyObject* args)
|
path_transform(PyPathObject *self, PyObject *args) {
|
||||||
{
|
|
||||||
/* Apply affine transform to coordinate set */
|
/* Apply affine transform to coordinate set */
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
double *xy;
|
double *xy;
|
||||||
|
@ -508,9 +488,8 @@ path_transform(PyPathObject* self, PyObject* args)
|
||||||
|
|
||||||
double wrap = 0.0;
|
double wrap = 0.0;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "(dddddd)|d:transform",
|
if (!PyArg_ParseTuple(
|
||||||
&a, &b, &c, &d, &e, &f,
|
args, "(dddddd)|d:transform", &a, &b, &c, &d, &e, &f, &wrap)) {
|
||||||
&wrap)) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,15 +533,11 @@ static struct PyMethodDef methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_getattr_id(PyPathObject* self, void* closure)
|
path_getattr_id(PyPathObject *self, void *closure) {
|
||||||
{
|
|
||||||
return Py_BuildValue("n", (Py_ssize_t)self->xy);
|
return Py_BuildValue("n", (Py_ssize_t)self->xy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct PyGetSetDef getsetters[] = {
|
static struct PyGetSetDef getsetters[] = {{"id", (getter)path_getattr_id}, {NULL}};
|
||||||
{ "id", (getter) path_getattr_id },
|
|
||||||
{ NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
path_subscript(PyPathObject *self, PyObject *item) {
|
path_subscript(PyPathObject *self, PyObject *item) {
|
||||||
|
@ -585,17 +560,15 @@ path_subscript(PyPathObject* self, PyObject* item) {
|
||||||
if (slicelength <= 0) {
|
if (slicelength <= 0) {
|
||||||
double *xy = alloc_array(0);
|
double *xy = alloc_array(0);
|
||||||
return (PyObject *)path_new(0, xy, 0);
|
return (PyObject *)path_new(0, xy, 0);
|
||||||
}
|
} else if (step == 1) {
|
||||||
else if (step == 1) {
|
|
||||||
return path_getslice(self, start, stop);
|
return path_getslice(self, start, stop);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "slice steps not supported");
|
PyErr_SetString(PyExc_TypeError, "slice steps not supported");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
PyErr_Format(
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyExc_TypeError,
|
||||||
"Path indices must be integers, not %.200s",
|
"Path indices must be integers, not %.200s",
|
||||||
Py_TYPE(item)->tp_name);
|
Py_TYPE(item)->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -613,14 +586,10 @@ static PySequenceMethods path_as_sequence = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMappingMethods path_as_mapping = {
|
static PyMappingMethods path_as_mapping = {
|
||||||
(lenfunc)path_len,
|
(lenfunc)path_len, (binaryfunc)path_subscript, NULL};
|
||||||
(binaryfunc)path_subscript,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject PyPathType = {
|
static PyTypeObject PyPathType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0) "Path", /*tp_name*/
|
||||||
"Path", /*tp_name*/
|
|
||||||
sizeof(PyPathObject), /*tp_size*/
|
sizeof(PyPathObject), /*tp_size*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
/* methods */
|
/* methods */
|
||||||
|
@ -651,4 +620,3 @@ static PyTypeObject PyPathType = {
|
||||||
0, /*tp_members*/
|
0, /*tp_members*/
|
||||||
getsetters, /*tp_getset*/
|
getsetters, /*tp_getset*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user