added dependencies and build files (loosely inspired by Sebastian Dorda's love-native-android)

This commit is contained in:
Martin Felis
2013-12-05 17:58:37 +01:00
parent 9604528a96
commit 95a086a47f
3700 changed files with 1691119 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
#include <stdio.h>
#if defined(_WIN32) && defined(_MEM_DEBUG)
#include <windows.h>
int bAtexit = 0;
typedef struct ALLOC_INFO
{
unsigned long address;
unsigned long size;
char file[64];
unsigned long line;
struct ALLOC_INFO *Next;
} ALLOC_INFO;
ALLOC_INFO *AllocList;
void AddTrack(unsigned long addr, unsigned long size, const char *file, unsigned long line)
{
ALLOC_INFO *Temp;
if (AllocList == NULL) {
AllocList = (ALLOC_INFO*)malloc(sizeof(ALLOC_INFO)); // Just assume it succeeds.
AllocList->address = addr;
AllocList->size = size;
AllocList->line = line;
strncpy(AllocList->file, file, 63);
AllocList->Next = NULL;
}
else {
Temp = AllocList;
AllocList = (ALLOC_INFO*)malloc(sizeof(ALLOC_INFO)); // Just assume it succeeds.
AllocList->address = addr;
AllocList->size = size;
AllocList->line = line;
strncpy(AllocList->file, file, 63);
AllocList->Next = Temp;
}
return;
}
void RemoveTrack(unsigned long addr)
{
ALLOC_INFO *Temp, *Prev;
Temp = AllocList;
Prev = NULL;
if (Temp == NULL)
return;
while (Temp != NULL) {
if (Temp->address == addr) {
if (Prev == NULL) {
AllocList = Temp->Next;
free(Temp);
}
else {
Prev->Next = Temp->Next;
free(Temp);
}
break;
}
Prev = Temp;
Temp = Temp->Next;
}
return;
}
void DumpUnfreed(void)
{
unsigned long TotalSize = 0;
char buf[1024];
ALLOC_INFO *i = AllocList;
OutputDebugString("ILU Unfreed Information:\n");
while (i != NULL) {
sprintf(buf, "%s(%d) : %d bytes unfreed at %d\n", i->file, i->line, i->size, i->address);
OutputDebugString(buf);
TotalSize += i->size;
AllocList = i->Next;
free(i);
i = AllocList;
}
sprintf(buf, "-----------------------------------------------------------\n");
OutputDebugString(buf);
sprintf(buf, "Total Unfreed: %d bytes\n\n\n", TotalSize);
OutputDebugString(buf);
}
void AddToAtexit()
{
if (bAtexit)
return;
atexit(DumpUnfreed);
bAtexit = 1;
}
void *c_alloc(unsigned long size, unsigned long num, const char *file, unsigned long line)
{
ILvoid *ptr;
ptr = calloc(size, num);
if (!ptr)
return NULL;
AddToAtexit();
AddTrack((unsigned long)ptr, size * num, file, line);
return ptr;
}
void *m_alloc(unsigned long size, const char *file, unsigned long line)
{
ILvoid *ptr;
ptr = malloc(size);
if (!ptr)
return NULL;
AddToAtexit();
AddTrack((unsigned long)ptr, size, file, line);
return ptr;
}
void f_ree(void *ptr)
{
RemoveTrack((unsigned long)ptr);
free(ptr);
return;
}
#endif//defined(_WIN32) && defined(_MEM_DEBUG)
+104
View File
@@ -0,0 +1,104 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/03/2009
//
// Filename: src-ILU/src/ilu_error.c
//
// Description: Error functions
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
#include "ilu_error/ilu_err-arabic.h"
#include "ilu_error/ilu_err-dutch.h"
#include "ilu_error/ilu_err-english.h"
#include "ilu_error/ilu_err-japanese.h"
#include "ilu_error/ilu_err-spanish.h"
#include "ilu_error/ilu_err-german.h"
#include "ilu_error/ilu_err-french.h"
ILconst_string *iluErrors;
ILconst_string *iluLibErrors;
ILconst_string *iluMiscErrors;
#define ILU_NUM_LANGUAGES 7
ILconst_string *iluErrorStrings[ILU_NUM_LANGUAGES] = {
iluErrorStringsEnglish,
iluErrorStringsArabic,
iluErrorStringsDutch,
iluErrorStringsFrench,
iluErrorStringsJapanese,
iluErrorStringsSpanish,
iluErrorStringsGerman
};
ILconst_string *iluLibErrorStrings[ILU_NUM_LANGUAGES] = {
iluLibErrorStringsEnglish,
iluLibErrorStringsArabic,
iluLibErrorStringsDutch,
iluLibErrorStringsFrench,
iluLibErrorStringsJapanese,
iluLibErrorStringsSpanish,
iluLibErrorStringsGerman
};
ILconst_string *iluMiscErrorStrings[ILU_NUM_LANGUAGES] = {
iluMiscErrorStringsEnglish,
iluMiscErrorStringsArabic,
iluMiscErrorStringsDutch,
iluMiscErrorStringsFrench,
iluMiscErrorStringsJapanese,
iluMiscErrorStringsSpanish,
iluMiscErrorStringsGerman
};
ILconst_string ILAPIENTRY iluErrorString(ILenum Error)
{
// Now we are dealing with Unicode strings.
if (Error == IL_NO_ERROR) {
return iluMiscErrors[0];
}
if (Error == IL_UNKNOWN_ERROR) {
return iluMiscErrors[1];
}
if (Error >= IL_INVALID_ENUM && Error <= IL_FILE_READ_ERROR) {
return (ILstring)iluErrors[Error - IL_INVALID_ENUM];
}
if (Error >= IL_LIB_GIF_ERROR && Error <= IL_LIB_EXR_ERROR) {
return (ILstring)iluLibErrors[Error - IL_LIB_GIF_ERROR];
}
return iluMiscErrors[0];
}
ILboolean ILAPIENTRY iluSetLanguage(ILenum Language)
{
switch (Language)
{
case ILU_ENGLISH:
case ILU_ARABIC:
case ILU_DUTCH:
case ILU_FRENCH:
case ILU_JAPANESE:
case ILU_SPANISH:
case ILU_GERMAN:
iluErrors = iluErrorStrings[Language - ILU_ENGLISH];
iluLibErrors = iluLibErrorStrings[Language - ILU_ENGLISH];
iluMiscErrors = iluMiscErrorStrings[Language - ILU_ENGLISH];
break;
default:
ilSetError(IL_INVALID_ENUM);
return IL_FALSE;
}
return IL_TRUE;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,491 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 10/12/2001 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_filter_rcg.c
//
// Description: Scales an image. Based on the Graphic Gems III source.
//
//-----------------------------------------------------------------------------
/*
* Filtered Image Rescaling
*
* by Dale Schumacher
*
*/
/*
Additional changes by Ray Gardener, Daylon Graphics Ltd.
December 4, 1999
Summary:
- Horizontal filter contributions are calculated on the fly,
as each column is mapped from src to dst image. This lets
us omit having to allocate a temporary full horizontal stretch
of the src image.
- If none of the src pixels within a sampling region differ,
then the output pixel is forced to equal (any of) the source pixel.
This ensures that filters do not corrupt areas of constant color.
- Filter weight contribution results, after summing, are
rounded to the nearest pixel color value instead of
being casted to ILubyte (usually an int or char). Otherwise,
artifacting occurs.
- All memory allocations checked for failure; zoom() returns
error code. new_image() returns NULL if unable to allocate
pixel storage, even if Image struct can be allocated.
Some assertions added.
- load_image(), save_image() take filenames, not file handles.
- TGA bitmap format available. If you want to add a filetype,
extend the gImageHandlers array, and factor in your load_image_xxx()
and save_image_xxx() functions. Search for string 'add your'
to find appropriate code locations.
- The 'input' and 'output' command-line arguments do not have
to specify .bm files; any supported filetype is okay.
- Added implementation of getopt() if compiling under Windows.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <malloc.h>
#include <math.h>
#include "ilu_internal.h"
#include "ilu_filter.h"
#include "ilu_states.h"
#define filter_support (1.0)
double filter( double t) {
/* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
if(t < 0.0) t = -t;
if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0);
return(0.0);
}
#define box_support (0.5)
double box_filter( double t) {
if((t > -0.5) && (t <= 0.5)) return(1.0);
return(0.0);
}
#define triangle_support (1.0)
double triangle_filter( double t ) {
if(t < 0.0) t = -t;
if(t < 1.0) return(1.0 - t);
return(0.0);
}
#define bell_support (1.5)
double bell_filter( double t ) {
if(t < 0) t = -t;
if(t < .5) return(.75 - (t * t));
if(t < 1.5) {
t = (t - 1.5);
return(.5 * (t * t));
}
return(0.0);
}
#define B_spline_support (2.0)
#define FRAC_2_3 0.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667
#define FRAC_1_6 0.1666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667
double B_spline_filter( double t ) { /* box (*) box (*) box (*) box */
double tt;
if(t < 0) t = -t;
if(t < 1) {
tt = t * t;
return((.5 * tt * t) - tt + (2.0 / 3.0));
} else if(t < 2) {
t = 2 - t;
return((1.0 / 6.0) * (t * t * t));
}
return(0.0);
}
double sinc( double x) {
x *= IL_PI;
if(x != 0) return(sin(x) / x);
return(1.0);
}
#define Lanczos3_support (3.0)
double Lanczos3_filter( double t ) {
if(t < 0) t = -t;
if(t < 3.0) return(sinc(t) * sinc(t/3.0));
return(0.0);
}
#define Mitchell_support (2.0)
#define B (1.0 / 3.0)
#define C (1.0 / 3.0)
double Mitchell_filter( double t ) {
double tt;
tt = t * t;
if(t < 0) t = -t;
if(t < 1.0) {
t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt))
+ ((-18.0 + 12.0 * B + 6.0 * C) * tt)
+ (6.0 - 2 * B));
return(t / 6.0);
} else if(t < 2.0) {
t = (((-1.0 * B - 6.0 * C) * (t * tt))
+ ((6.0 * B + 30.0 * C) * tt)
+ ((-12.0 * B - 48.0 * C) * t)
+ (8.0 * B + 24 * C));
return(t / 6.0);
}
return(0.0);
}
int roundcloser(double d) {
int n = (int) d;
double diff = d - (double)n;
if(diff < 0)
diff = -diff;
if(diff >= 0.5)
{
if(d < 0)
n--;
else
n++;
}
return n;
}
int wrap_filter_sample(int i, int size) {
int j;
j = i % (size * 2);
if (j < 0)
j += (size * 2);
if (j < size)
return j;
return 2 * size - j - 1;
}
/*char _Program[] = "fzoom";
char _Version[] = "0.30";
char _Copyright[] = "Public Domain 1991 by Dale Schumacher. Mods by Ray Gardener";*/
/* Note: if you define ILubyte to something bigger than char,
you may need to add more support in bitmap file I/O functions.
*/
#define WHITE_PIXEL (255)
#define BLACK_PIXEL (0)
#define CLAMP(v,l,h) ((v)<(l) ? (l) : (v) > (h) ? (h) : v)
static ILuint c; // Current colour plane offset
typedef struct {
int pixel;
double weight;
} CONTRIB;
typedef struct {
int n; /* number of contributors */
CONTRIB *p; /* pointer to list of contributions */
} CLIST;
CLIST *contrib; /* array of contribution lists */
/*
* generic image access and i/o support routines
*/
/*
calc_x_contrib()
Calculates the filter weights for a single target column.
contribX->p must be freed afterwards.
Returns -1 if error, 0 otherwise.
*/
int calc_x_contrib( CLIST *contribX, double xscale, double fwidth, int dstwidth, int srcwidth, double (*filterf)(double), int i) {
double width;
double fscale;
double center, left, right;
double weight;
int j, k, n;
if(xscale < 1.0)
{
/* Shrinking image */
width = fwidth / xscale;
fscale = 1.0 / xscale;
contribX->n = 0;
contribX->p = (CONTRIB *)icalloc((int) (width * 2 + 1),
sizeof(CONTRIB));
if (contribX->p == NULL) {
return -1;
}
center = (double) i / xscale;
left = ceil(center - width);
right = floor(center + width);
for(j = (int)left; j <= right; ++j)
{
weight = center - (double) j;
weight = (*filterf)(weight / fscale) / fscale;
n = wrap_filter_sample(j, srcwidth);
k = contribX->n++;
contribX->p[k].pixel = n;
contribX->p[k].weight = weight;
}
}
else
{
/* Expanding image */
contribX->n = 0;
contribX->p = (CONTRIB*)icalloc((int) (fwidth * 2 + 1),
sizeof(CONTRIB));
if (contribX->p == NULL) {
return -1;
}
center = (double) i / xscale;
left = ceil(center - fwidth);
right = floor(center + fwidth);
for(j = (int)left; j <= right; ++j)
{
weight = center - (double) j;
weight = (*filterf)(weight);
n = wrap_filter_sample(j, srcwidth);
k = contribX->n++;
contribX->p[k].pixel = n;
contribX->p[k].weight = weight;
}
}
return 0;
} /* calc_x_contrib */
/*
zoom()
Resizes bitmaps while resampling them.
Returns -1 if error, 0 if success.
*/
int zoom( ILimage *dst, ILimage *src, double (*filterf)(double), double fwidth) {
ILubyte* tmp;
double xscale, yscale; /* zoom scale factors */
int xx;
int i, j, k; /* loop variables */
int n; /* pixel number */
double center, left, right; /* filter calculation variables */
double width, fscale, weight; /* filter calculation variables */
ILubyte pel, pel2;
int bPelDelta;
CLIST *contribY; /* array of contribution lists */
CLIST contribX;
int nRet = -1;
/* create intermediate column to hold horizontal dst column zoom */
tmp = (ILubyte*)ialloc(src->Height * sizeof(ILubyte));
if (tmp == NULL) {
return 0;
}
xscale = (double) dst->Width / (double) src->Width;
/* Build y weights */
/* pre-calculate filter contributions for a column */
contribY = (CLIST*)icalloc(dst->Height, sizeof(CLIST));
if (contribY == NULL) {
ifree(tmp);
return -1;
}
yscale = (double) dst->Height / (double) src->Height;
if(yscale < 1.0)
{
width = fwidth / yscale;
fscale = 1.0 / yscale;
for(i = 0; i < (ILint)dst->Height; ++i)
{
contribY[i].n = 0;
contribY[i].p = (CONTRIB*)icalloc((int) (width * 2 + 1),
sizeof(CONTRIB));
if(contribY[i].p == NULL) {
ifree(tmp);
ifree(contribY);
return -1;
}
center = (double) i / yscale;
left = ceil(center - width);
right = floor(center + width);
for(j = (int)left; j <= right; ++j) {
weight = center - (double) j;
weight = (*filterf)(weight / fscale) / fscale;
n = wrap_filter_sample(j, src->Height);
k = contribY[i].n++;
contribY[i].p[k].pixel = n;
contribY[i].p[k].weight = weight;
}
}
} else {
for(i = 0; i < (ILint)dst->Height; ++i) {
contribY[i].n = 0;
contribY[i].p = (CONTRIB*)icalloc((int) (fwidth * 2 + 1),
sizeof(CONTRIB));
if (contribY[i].p == NULL) {
ifree(tmp);
ifree(contribY);
return -1;
}
center = (double) i / yscale;
left = ceil(center - fwidth);
right = floor(center + fwidth);
for(j = (int)left; j <= right; ++j) {
weight = center - (double) j;
weight = (*filterf)(weight);
n = wrap_filter_sample(j, src->Height);
k = contribY[i].n++;
contribY[i].p[k].pixel = n;
contribY[i].p[k].weight = weight;
}
}
}
for(xx = 0; xx < (ILint)dst->Width; xx++)
{
if(0 != calc_x_contrib(&contribX, xscale, fwidth,
dst->Width, src->Width, filterf, xx))
{
goto __zoom_cleanup;
}
/* Apply horz filter to make dst column in tmp. */
for(k = 0; k < (ILint)src->Height; ++k)
{
weight = 0.0;
bPelDelta = IL_FALSE;
// Denton: Put get_pixel source here
//pel = get_pixel(src, contribX.p[0].pixel, k);
pel = src->Data[k * src->Bps + contribX.p[0].pixel * src->Bpp + c];
for(j = 0; j < contribX.n; ++j)
{
// Denton: Put get_pixel source here
//pel2 = get_pixel(src, contribX.p[j].pixel, k);
pel2 = src->Data[k * src->Bps + contribX.p[j].pixel * src->Bpp + c];
if(pel2 != pel)
bPelDelta = IL_TRUE;
weight += pel2 * contribX.p[j].weight;
}
weight = bPelDelta ? roundcloser(weight) : pel;
tmp[k] = (ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL);
} /* next row in temp column */
ifree(contribX.p);
/* The temp column has been built. Now stretch it
vertically into dst column. */
for(i = 0; i < (ILint)dst->Height; ++i)
{
weight = 0.0;
bPelDelta = IL_FALSE;
pel = tmp[contribY[i].p[0].pixel];
for(j = 0; j < contribY[i].n; ++j)
{
pel2 = tmp[contribY[i].p[j].pixel];
if(pel2 != pel)
bPelDelta = IL_TRUE;
weight += pel2 * contribY[i].p[j].weight;
}
weight = bPelDelta ? roundcloser(weight) : pel;
// Denton: Put set_pixel source here
//put_pixel(dst, xx, i, (ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL));
dst->Data[i * dst->Bps + xx * dst->Bpp + c] =
(ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL);
} /* next dst row */
} /* next dst column */
nRet = 0; /* success */
__zoom_cleanup:
ifree(tmp);
// Free the memory allocated for vertical filter weights
for (i = 0; i < (ILint)dst->Height; ++i)
ifree(contribY[i].p);
ifree(contribY);
return nRet;
} /* zoom */
ILuint iluScaleAdvanced(ILuint Width, ILuint Height, ILenum Filter)
{
double (*f)(double) = filter;
double s = filter_support;
ILimage *Dest;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
// Not supported yet.
if (iluCurImage->Type != IL_UNSIGNED_BYTE ||
iluCurImage->Format == IL_COLOUR_INDEX ||
iluCurImage->Depth > 1) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
switch (Filter)
{
case ILU_SCALE_BOX: f=box_filter; s=box_support; break;
case ILU_SCALE_TRIANGLE: f=triangle_filter; s=triangle_support; break;
case ILU_SCALE_BELL: f=bell_filter; s=bell_support; break;
case ILU_SCALE_BSPLINE: f=B_spline_filter; s=B_spline_support; break;
case ILU_SCALE_LANCZOS3: f=Lanczos3_filter; s=Lanczos3_support; break;
case ILU_SCALE_MITCHELL: f=Mitchell_filter; s=Mitchell_support; break;
//case 'h': f=filter; s=filter_support; break;
}
Dest = ilNewImage(Width, Height, 1, iluCurImage->Bpp, 1);
Dest->Origin = iluCurImage->Origin;
Dest->Duration = iluCurImage->Duration;
for (c = 0; c < (ILuint)iluCurImage->Bpp; c++) {
if (zoom(Dest, iluCurImage, f, s) != 0) {
return IL_FALSE;
}
}
ilTexImage(Width, Height, 1, iluCurImage->Bpp, iluCurImage->Format, iluCurImage->Type, Dest->Data);
iluCurImage->Origin = Dest->Origin;
iluCurImage->Duration = Dest->Duration;
ilCloseImage(Dest);
return IL_TRUE;
}
@@ -0,0 +1,9 @@
#define ILU_INTERNAL_C
#include "ilu_internal.h"
const ILdouble IL_PI = 3.1415926535897932384626;
const ILdouble IL_DEGCONV = 0.0174532925199432957692;
ILimage *iluCurImage = NULL;
+71
View File
@@ -0,0 +1,71 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/20/2001 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_main.c
//
// Description: Startup functions
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
#include "ilu_states.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif//_WIN32
#ifdef _WIN32
#if (defined(IL_USE_PRAGMA_LIBS))
#if defined(_MSC_VER) || defined(__BORLANDC__)
#pragma comment(lib, "DevIL.lib")
#endif
#endif
#endif
/* Only needed for MSVC++ unless extended to actually do something =) */
#if defined(_WIN32) && defined(_MSC_VER)
#ifndef IL_STATIC_LIB
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
hModule; ul_reason_for_call; lpReserved;
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
//iluInit();
}
return TRUE;
}
#endif
#endif
void ILAPIENTRY iluInit()
{
// Used mostly for rotations
//IL_PI = 4 * atan(1); // precomputed value of pi
//IL_DEGCONV = IL_PI / 180; // division is slow on some computers
iluSetLanguage(ILU_ENGLISH);
return;
}
//#ifndef _WIN32_WCE
ILuint ILAPIENTRY iluLoadImage(ILconst_string FileName)
{
ILuint Id;
ilGenImages(1, &Id);
if (Id == 0)
return 0;
if (!ilLoadImage(FileName)) {
ilDeleteImages(1, &Id);
return 0;
}
return Id;
}
//#endif//_WIN32_WCE
+905
View File
@@ -0,0 +1,905 @@
#include "ilu_internal.h"
#include "ilu_states.h"
#include <float.h>
#include <limits.h>
ILboolean iluCrop2D(ILuint XOff, ILuint YOff, ILuint Width, ILuint Height) {
ILuint x, y, c, OldBps;
ILubyte *Data;
ILenum Origin;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
// Uh-oh, what about 0 dimensions?!
if (Width > iluCurImage->Width || Height > iluCurImage->Height) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
Data = (ILubyte*)ialloc(iluCurImage->SizeOfData);
if (Data == NULL) {
return IL_FALSE;
}
OldBps = iluCurImage->Bps;
Origin = iluCurImage->Origin;
ilCopyPixels(0, 0, 0, iluCurImage->Width, iluCurImage->Height, 1, iluCurImage->Format, iluCurImage->Type, Data);
if (!ilTexImage(Width, Height, iluCurImage->Depth, iluCurImage->Bpp, iluCurImage->Format, iluCurImage->Type, NULL)) {
free(Data);
return IL_FALSE;
}
iluCurImage->Origin = Origin;
// @TODO: Optimize! (Especially XOff * iluCurImage->Bpp...get rid of it!)
for (y = 0; y < iluCurImage->Height; y++) {
for (x = 0; x < iluCurImage->Bps; x += iluCurImage->Bpp) {
for (c = 0; c < iluCurImage->Bpp; c++) {
iluCurImage->Data[y * iluCurImage->Bps + x + c] =
Data[(y + YOff) * OldBps + x + XOff * iluCurImage->Bpp + c];
}
}
}
ifree(Data);
return IL_TRUE;
}
ILboolean iluCrop3D(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth)
{
ILuint x, y, z, c, OldBps, OldPlane;
ILubyte *Data;
ILenum Origin;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
// Uh-oh, what about 0 dimensions?!
if (Width > iluCurImage->Width || Height > iluCurImage->Height || Depth > iluCurImage->Depth) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
Data = (ILubyte*)ialloc(iluCurImage->SizeOfData);
if (Data == NULL) {
return IL_FALSE;
}
OldBps = iluCurImage->Bps;
OldPlane = iluCurImage->SizeOfPlane;
Origin = iluCurImage->Origin;
ilCopyPixels(0, 0, 0, iluCurImage->Width, iluCurImage->Height, iluCurImage->Depth, iluCurImage->Format, iluCurImage->Type, Data);
if (!ilTexImage(Width - XOff, Height - YOff, Depth - ZOff, iluCurImage->Bpp, iluCurImage->Format, iluCurImage->Type, NULL)) {
ifree(Data);
}
iluCurImage->Origin = Origin;
for (z = 0; z < iluCurImage->Depth; z++) {
for (y = 0; y < iluCurImage->Height; y++) {
for (x = 0; x < iluCurImage->Bps; x += iluCurImage->Bpp) {
for (c = 0; c < iluCurImage->Bpp; c++) {
iluCurImage->Data[z * iluCurImage->SizeOfPlane + y * iluCurImage->Bps + x + c] =
Data[(z + ZOff) * OldPlane + (y + YOff) * OldBps + (x + XOff) + c];
}
}
}
}
ifree(Data);
return IL_TRUE;
}
ILboolean ILAPIENTRY iluCrop(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth)
{
if (ZOff <= 1)
return iluCrop2D(XOff, YOff, Width, Height);
return iluCrop3D(XOff, YOff, ZOff, Width, Height, Depth);
}
//! Enlarges the canvas
ILboolean ILAPIENTRY iluEnlargeCanvas(ILuint Width, ILuint Height, ILuint Depth)
{
ILubyte *Data/*, Clear[4]*/;
ILuint x, y, z, OldBps, OldH, OldD, OldPlane, AddX, AddY;
ILenum Origin;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
// Uh-oh, what about 0 dimensions?!
if (Width < iluCurImage->Width || Height < iluCurImage->Height || Depth < iluCurImage->Depth) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (iluCurImage->Origin == IL_ORIGIN_LOWER_LEFT) {
switch (iluPlacement)
{
case ILU_LOWER_LEFT:
AddX = 0;
AddY = 0;
break;
case ILU_LOWER_RIGHT:
AddX = Width - iluCurImage->Width;
AddY = 0;
break;
case ILU_UPPER_LEFT:
AddX = 0;
AddY = Height - iluCurImage->Height;
break;
case ILU_UPPER_RIGHT:
AddX = Width - iluCurImage->Width;
AddY = Height - iluCurImage->Height;
break;
case ILU_CENTER:
AddX = (Width - iluCurImage->Width) >> 1;
AddY = (Height - iluCurImage->Height) >> 1;
break;
default:
ilSetError(ILU_INVALID_PARAM);
return IL_FALSE;
}
}
else { // IL_ORIGIN_UPPER_LEFT
switch (iluPlacement)
{
case ILU_LOWER_LEFT:
AddX = 0;
AddY = Height - iluCurImage->Height;
break;
case ILU_LOWER_RIGHT:
AddX = Width - iluCurImage->Width;
AddY = Height - iluCurImage->Height;
break;
case ILU_UPPER_LEFT:
AddX = 0;
AddY = 0;
break;
case ILU_UPPER_RIGHT:
AddX = Width - iluCurImage->Width;
AddY = 0;
break;
case ILU_CENTER:
AddX = (Width - iluCurImage->Width) >> 1;
AddY = (Height - iluCurImage->Height) >> 1;
break;
default:
ilSetError(ILU_INVALID_PARAM);
return IL_FALSE;
}
}
AddX *= iluCurImage->Bpp;
Data = (ILubyte*)ialloc(iluCurImage->SizeOfData);
if (Data == NULL) {
return IL_FALSE;
}
// Preserve old data.
OldPlane = iluCurImage->SizeOfPlane;
OldBps = iluCurImage->Bps;
OldH = iluCurImage->Height;
OldD = iluCurImage->Depth;
Origin = iluCurImage->Origin;
ilCopyPixels(0, 0, 0, iluCurImage->Width, iluCurImage->Height, OldD, iluCurImage->Format, iluCurImage->Type, Data);
ilTexImage(Width, Height, Depth, iluCurImage->Bpp, iluCurImage->Format, iluCurImage->Type, NULL);
iluCurImage->Origin = Origin;
ilClearImage();
/*ilGetClear(Clear);
if (iluCurImage->Bpp == 1) {
memset(iluCurImage->Data, Clear[3], iluCurImage->SizeOfData);
}
else {
for (x = 0; x < iluCurImage->SizeOfData; x += iluCurImage->Bpp) {
for (y = 0; y < iluCurImage->Bpp; y++) {
iluCurImage->Data[y] = Clear[y];
}
}
}*/
for (z = 0; z < OldD; z++) {
for (y = 0; y < OldH; y++) {
for (x = 0; x < OldBps; x++) {
iluCurImage->Data[z * iluCurImage->SizeOfPlane + (y + AddY) * iluCurImage->Bps + x + AddX] =
Data[z * OldPlane + y * OldBps + x];
}
}
}
ifree(Data);
return IL_TRUE;
}
//! Flips an image over its x axis
ILboolean ILAPIENTRY iluFlipImage() {
//ILubyte *StartPtr, *EndPtr;
//ILuint y, d;
ILimage *image = ilGetCurImage();
if( image == NULL ) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
iFlipBuffer(image->Data,image->Depth,image->Bps,image->Height);
/*
for( d = 0; d < image->Depth; d++ ) {
StartPtr = image->Data + d * image->SizeOfPlane;
EndPtr = image->Data + d * image->SizeOfPlane
+ image->SizeOfPlane;
for( y = 0; y < (image->Height/2); y++ ) {
EndPtr -= image->Bps;
iMemSwap(StartPtr,EndPtr,image->Bps);
StartPtr += image->Bps;
}
}
*/
return IL_TRUE;
}
//! Mirrors an image over its y axis
ILboolean ILAPIENTRY iluMirror() {
return iMirror();
}
//! Inverts the alpha in the image
ILboolean ILAPIENTRY iluInvertAlpha() {
ILuint i, *IntPtr, NumPix;
ILubyte *Data;
ILushort *ShortPtr;
ILfloat *FltPtr;
ILdouble *DblPtr;
ILubyte Bpp;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (iluCurImage->Format != IL_RGBA &&
iluCurImage->Format != IL_BGRA &&
iluCurImage->Format != IL_LUMINANCE_ALPHA) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
Data = iluCurImage->Data;
Bpp = iluCurImage->Bpp;
NumPix = iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth;
switch (iluCurImage->Type)
{
case IL_BYTE:
case IL_UNSIGNED_BYTE:
Data += (Bpp - 1);
for( i = Bpp - 1; i < NumPix; i++, Data += Bpp )
*(Data) = ~*(Data);
break;
case IL_SHORT:
case IL_UNSIGNED_SHORT:
ShortPtr = ((ILushort*)Data) + Bpp-1;
for (i = Bpp - 1; i < NumPix; i++, ShortPtr += Bpp)
*(ShortPtr) = ~*(ShortPtr);
break;
case IL_INT:
case IL_UNSIGNED_INT:
IntPtr = ((ILuint*)Data) + Bpp-1;
for (i = Bpp - 1; i < NumPix; i++, IntPtr += Bpp)
*(IntPtr) = ~*(IntPtr);
break;
case IL_FLOAT:
FltPtr = ((ILfloat*)Data) + Bpp - 1;
for (i = Bpp - 1; i < NumPix; i++, FltPtr += Bpp)
*(FltPtr) = 1.0f - *(FltPtr);
break;
case IL_DOUBLE:
DblPtr = ((ILdouble*)Data) + Bpp - 1;
for (i = Bpp - 1; i < NumPix; i++, DblPtr += Bpp)
*(DblPtr) = 1.0f - *(DblPtr);
break;
}
return IL_TRUE;
}
//! Inverts the colours in the image
ILboolean ILAPIENTRY iluNegative()
{
ILuint i, j, c, *IntPtr, NumPix, Bpp;
ILubyte *Data;
ILushort *ShortPtr;
ILubyte *RegionMask;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (iluCurImage->Format == IL_COLOUR_INDEX) {
if (!iluCurImage->Pal.Palette || !iluCurImage->Pal.PalSize || iluCurImage->Pal.PalType == IL_PAL_NONE) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
Data = iluCurImage->Pal.Palette;
i = iluCurImage->Pal.PalSize;
}
else {
Data = iluCurImage->Data;
i = iluCurImage->SizeOfData;
}
RegionMask = iScanFill();
// @TODO: Optimize this some.
NumPix = i / iluCurImage->Bpc;
Bpp = iluCurImage->Bpp;
if (RegionMask) {
switch (iluCurImage->Bpc)
{
case 1:
for (j = 0, i = 0; j < NumPix; j += Bpp, i++, Data += Bpp) {
for (c = 0; c < Bpp; c++) {
if (RegionMask[i])
*(Data+c) = ~*(Data+c);
}
}
break;
case 2:
ShortPtr = (ILushort*)Data;
for (j = 0, i = 0; j < NumPix; j += Bpp, i++, ShortPtr += Bpp) {
for (c = 0; c < Bpp; c++) {
if (RegionMask[i])
*(ShortPtr+c) = ~*(ShortPtr+c);
}
}
break;
case 4:
IntPtr = (ILuint*)Data;
for (j = 0, i = 0; j < NumPix; j += Bpp, i++, IntPtr += Bpp) {
for (c = 0; c < Bpp; c++) {
if (RegionMask[i])
*(IntPtr+c) = ~*(IntPtr+c);
}
}
break;
}
}
else {
switch (iluCurImage->Bpc)
{
case 1:
for (j = 0; j < NumPix; j++, Data++) {
*(Data) = ~*(Data);
}
break;
case 2:
ShortPtr = (ILushort*)Data;
for (j = 0; j < NumPix; j++, ShortPtr++) {
*(ShortPtr) = ~*(ShortPtr);
}
break;
case 4:
IntPtr = (ILuint*)Data;
for (j = 0; j < NumPix; j++, IntPtr++) {
*(IntPtr) = ~*(IntPtr);
}
break;
}
}
ifree(RegionMask);
return IL_TRUE;
}
// Taken from
// http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue2.html#Insight
// Hope they don't mind too much. =]
ILboolean ILAPIENTRY iluWave(ILfloat Angle)
{
ILint Delta;
ILuint y;
ILubyte *DataPtr, *TempBuff;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
TempBuff = (ILubyte*)ialloc(iluCurImage->SizeOfData);
if (TempBuff == NULL) {
return IL_FALSE;
}
for (y = 0; y < iluCurImage->Height; y++) {
Delta = (ILint)
(30 * sin((10 * Angle + y) * IL_DEGCONV) +
15 * sin(( 7 * Angle + 3 * y) * IL_DEGCONV));
DataPtr = iluCurImage->Data + y * iluCurImage->Bps;
if (Delta < 0) {
Delta = -Delta;
memcpy(TempBuff, DataPtr, iluCurImage->Bpp * Delta);
memcpy(DataPtr, DataPtr + iluCurImage->Bpp * Delta, iluCurImage->Bpp * (iluCurImage->Width - Delta));
memcpy(DataPtr + iluCurImage->Bpp * (iluCurImage->Width - Delta), TempBuff, iluCurImage->Bpp * Delta);
}
else if (Delta > 0) {
memcpy(TempBuff, DataPtr, iluCurImage->Bpp * (iluCurImage->Width - Delta));
memcpy(DataPtr, DataPtr + iluCurImage->Bpp * (iluCurImage->Width - Delta), iluCurImage->Bpp * Delta);
memcpy(DataPtr + iluCurImage->Bpp * Delta, TempBuff, iluCurImage->Bpp * (iluCurImage->Width - Delta));
}
}
ifree(TempBuff);
return IL_TRUE;
}
// Swaps the colour order of the current image (rgb(a)->bgr(a) or vice-versa).
// Must be either an 8, 24 or 32-bit (coloured) image (or palette).
ILboolean ILAPIENTRY iluSwapColours() {
// Use ilConvert or other like that to convert the data?
// and extend that function to work even on paletted data
ILimage *img = ilGetCurImage();
if( img == NULL ) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (iluCurImage->Bpp == 1) {
if (ilGetBppPal(iluCurImage->Pal.PalType) == 0 || iluCurImage->Format != IL_COLOUR_INDEX) {
ilSetError(ILU_ILLEGAL_OPERATION); // Can be luminance.
return IL_FALSE;
}
switch( img->Pal.PalType ) {
case IL_PAL_RGB24:
return ilConvertPal(IL_PAL_BGR24);
case IL_PAL_RGB32:
return ilConvertPal(IL_PAL_BGR32);
case IL_PAL_RGBA32:
return ilConvertPal(IL_PAL_BGRA32);
case IL_PAL_BGR24:
return ilConvertPal(IL_PAL_RGB24);
case IL_PAL_BGR32:
return ilConvertPal(IL_PAL_RGB32);
case IL_PAL_BGRA32:
return ilConvertPal(IL_PAL_RGBA32);
default:
ilSetError(ILU_INTERNAL_ERROR);
return IL_FALSE;
}
}
switch( img->Format) {
case IL_RGB:
return ilConvertImage(IL_BGR, img->Type);
case IL_RGBA:
return ilConvertImage(IL_BGRA, img->Type);
case IL_BGR:
return ilConvertImage(IL_RGB, img->Type);
case IL_BGRA:
return ilConvertImage(IL_RGBA, img->Type);
}
ilSetError(ILU_INTERNAL_ERROR);
return IL_FALSE;
}
typedef struct BUCKET { ILubyte Colours[4]; struct BUCKET *Next; } BUCKET;
ILuint ILAPIENTRY iluColoursUsed()
{
ILuint i, c, Bpp, ColVal, SizeData, BucketPos = 0, NumCols = 0;
BUCKET Buckets[8192], *Temp;
ILubyte ColTemp[4];
ILboolean Matched;
BUCKET *Heap[9];
ILuint HeapPos = 0, HeapPtr = 0, HeapSize;
imemclear(Buckets, sizeof(BUCKET) * 8192);
for (c = 0; c < 9; c++) {
Heap[c] = 0;
}
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return 0;
}
Bpp = iluCurImage->Bpp;
SizeData = iluCurImage->SizeOfData;
// Create our miniature memory heap.
// I have determined that the average number of colours versus
// the number of pixels is about a 1:8 ratio, so divide by 8.
HeapSize = IL_MAX(1, iluCurImage->SizeOfData / iluCurImage->Bpp / 8);
Heap[0] = (BUCKET*)ialloc(HeapSize * sizeof(BUCKET));
if (Heap[0] == NULL)
return IL_FALSE;
for (i = 0; i < SizeData; i += Bpp) {
*(ILuint*)ColTemp = 0;
/*for (c = 0; c < Bpp; c++) {
ColTemp[c] = iluCurImage->Data[i + c];
}*/
ColTemp[0] = iluCurImage->Data[i];
if (Bpp > 1) {
ColTemp[1] = iluCurImage->Data[i + 1];
ColTemp[2] = iluCurImage->Data[i + 2];
}
if (Bpp > 3)
ColTemp[3] = iluCurImage->Data[i + 3];
BucketPos = *(ILuint*)ColTemp % 8192;
// Add to hash table
if (Buckets[BucketPos].Next == NULL) {
NumCols++;
//Buckets[BucketPos].Next = (BUCKET*)ialloc(sizeof(BUCKET));
Buckets[BucketPos].Next = Heap[HeapPos] + HeapPtr++;
if (HeapPtr >= HeapSize) {
Heap[++HeapPos] = (BUCKET*)ialloc(HeapSize * sizeof(BUCKET));
if (Heap[HeapPos] == NULL)
goto alloc_error;
HeapPtr = 0;
}
*(ILuint*)Buckets[BucketPos].Next->Colours = *(ILuint*)ColTemp;
Buckets[BucketPos].Next->Next = NULL;
}
else {
Matched = IL_FALSE;
Temp = Buckets[BucketPos].Next;
ColVal = *(ILuint*)ColTemp;
while (Temp->Next != NULL) {
if (ColVal == *(ILuint*)Temp->Colours) {
Matched = IL_TRUE;
break;
}
Temp = Temp->Next;
}
if (!Matched) {
if (ColVal != *(ILuint*)Temp->Colours) { // Check against last entry
NumCols++;
Temp = Buckets[BucketPos].Next;
//Buckets[BucketPos].Next = (BUCKET*)ialloc(sizeof(BUCKET));
Buckets[BucketPos].Next = Heap[HeapPos] + HeapPtr++;
if (HeapPtr >= HeapSize) {
Heap[++HeapPos] = (BUCKET*)ialloc(HeapSize * sizeof(BUCKET));
if (Heap[HeapPos] == NULL)
goto alloc_error;
HeapPtr = 0;
}
Buckets[BucketPos].Next->Next = Temp;
*(ILuint*)Buckets[BucketPos].Next->Colours = *(ILuint*)ColTemp;
}
}
}
}
// Delete our mini heap.
for (i = 0; i < 9; i++) {
if (Heap[i] == NULL)
break;
ifree(Heap[i]);
}
return NumCols;
alloc_error:
for (i = 0; i < 9; i++) {
ifree(Heap[i]);
}
return 0;
}
ILboolean ILAPIENTRY iluCompareImage(ILuint Comp)
{
ILimage *Original;
ILuint OrigName, i;
ILboolean Same = IL_TRUE;
iluCurImage = ilGetCurImage();
OrigName = ilGetCurName();
// Same image, so return true.
if (ilGetCurName() == Comp)
return IL_TRUE;
if (iluCurImage == NULL || ilIsImage(Comp) == IL_FALSE) {
ilSetError(ILU_ILLEGAL_OPERATION);
return 0;
}
ilBindImage(Comp);
Original = ilGetCurImage();
// @TODO: Should we check palettes, too?
if (Original->Bpp != iluCurImage->Bpp ||
Original->Depth != iluCurImage->Depth ||
Original->Format != iluCurImage->Format ||
Original->Height != iluCurImage->Height ||
Original->Origin != iluCurImage->Origin ||
Original->Type != iluCurImage->Type ||
Original->Width != iluCurImage->Width) {
ilBindImage(OrigName);
return IL_FALSE;
}
for (i = 0; i < iluCurImage->SizeOfData; i++) {
if (Original->Data[i] != iluCurImage->Data[i]) {
Same = IL_FALSE;
break;
}
}
ilBindImage(OrigName);
return Same;
}
// @TODO: FIX ILGETCLEARCALL!
ILboolean ILAPIENTRY iluReplaceColour(ILubyte Red, ILubyte Green, ILubyte Blue, ILfloat Tolerance)
{
ILubyte ClearCol[4];
ILint TolVal, Distance, Dist1, Dist2, Dist3;
ILuint i, NumPix;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return 0;
}
ilGetClear(ClearCol, IL_RGBA, IL_UNSIGNED_BYTE);
if (Tolerance > 1.0f || Tolerance < -1.0f)
Tolerance = 1.0f; // Clamp it.
TolVal = (ILuint)(fabs(Tolerance) * UCHAR_MAX); // To be changed.
NumPix = iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth;
if (Tolerance <= FLT_EPSILON && Tolerance >= 0) {
//@TODO what is this?
}
else {
switch (iluCurImage->Format)
{
case IL_RGB:
case IL_RGBA:
for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
Dist1 = (ILint)iluCurImage->Data[i] - (ILint)ClearCol[0];
Dist2 = (ILint)iluCurImage->Data[i+1] - (ILint)ClearCol[1];
Dist3 = (ILint)iluCurImage->Data[i+2] - (ILint)ClearCol[2];
Distance = (ILint)sqrt((float)(Dist1 * Dist1 + Dist2 * Dist2 + Dist3 * Dist3));
if (Distance >= -TolVal && Distance <= TolVal) {
iluCurImage->Data[i] = Red;
iluCurImage->Data[i+1] = Green;
iluCurImage->Data[i+2] = Blue;
}
}
break;
case IL_BGR:
case IL_BGRA:
for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
Dist1 = (ILint)iluCurImage->Data[i] - (ILint)ClearCol[0];
Dist2 = (ILint)iluCurImage->Data[i+1] - (ILint)ClearCol[1];
Dist3 = (ILint)iluCurImage->Data[i+2] - (ILint)ClearCol[2];
Distance = (ILint)sqrt((float)(Dist1 * Dist1 + Dist2 * Dist2 + Dist3 * Dist3));
if (Distance >= -TolVal && Distance <= TolVal) {
iluCurImage->Data[i+2] = Red;
iluCurImage->Data[i+1] = Green;
iluCurImage->Data[i] = Blue;
}
}
break;
case IL_LUMINANCE:
case IL_LUMINANCE_ALPHA:
for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
Dist1 = (ILint)iluCurImage->Data[i] - (ILint)ClearCol[0];
if (Dist1 >= -TolVal && Dist1 <= TolVal) {
iluCurImage->Data[i] = Blue;
}
}
break;
//case IL_COLOUR_INDEX: // @TODO
}
}
return IL_TRUE;
}
// Credit goes to Lionel Brits for this (refer to credits.txt)
ILboolean ILAPIENTRY iluEqualize() {
ILuint Histogram[256]; // image Histogram
ILuint SumHistm[256]; // normalized Histogram and LUT
ILuint i = 0; // index variable
ILuint j = 0; // index variable
ILuint Sum=0;
ILuint NumPixels, Bpp;
ILint Intensity;
ILfloat Scale;
ILint IntensityNew;
ILimage *LumImage;
ILuint NewColour[4];
ILubyte *BytePtr;
ILushort *ShortPtr;
ILuint *IntPtr;
NewColour[0] = NewColour[1] = NewColour[2] = NewColour[3] = 0;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return 0;
}
// @TODO: Change to work with other types!
if (iluCurImage->Bpc > 1) {
ilSetError(ILU_INTERNAL_ERROR);
return IL_FALSE;
}
if (iluCurImage->Format == IL_COLOUR_INDEX) {
NumPixels = iluCurImage->Pal.PalSize / ilGetBppPal(iluCurImage->Pal.PalType);
Bpp = ilGetBppPal(iluCurImage->Pal.PalType);
} else {
NumPixels = iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth;
Bpp = iluCurImage->Bpp;
}
// Clear the tables.
imemclear(Histogram, 256 * sizeof(ILuint));
imemclear(SumHistm, 256 * sizeof(ILuint));
LumImage = iConvertImage(iluCurImage, IL_LUMINANCE, IL_UNSIGNED_BYTE); // the type must be left as it is!
if (LumImage == NULL)
return IL_FALSE;
for (i = 0; i < NumPixels; i++) {
Histogram[LumImage->Data[i]]++;
}
// Calculate normalized Sum of Histogram.
for (i = 0; i < 256; i++) {
for (j = 0; j < i; j++)
Sum += Histogram[j];
SumHistm[i] = (Sum << 8) / NumPixels;
Sum = 0;
}
BytePtr = (iluCurImage->Format == IL_COLOUR_INDEX) ? iluCurImage->Pal.Palette : iluCurImage->Data;
ShortPtr = (ILushort*)iluCurImage->Data;
IntPtr = (ILuint*)iluCurImage->Data;
// Transform image using new SumHistm as a LUT
for (i = 0; i < NumPixels; i++) {
Intensity = LumImage->Data[i];
// Look up the normalized intensity
IntensityNew = (ILint)SumHistm[Intensity];
// Find out by how much the intensity has been Scaled
Scale = (ILfloat)IntensityNew / (ILfloat)Intensity;
switch (iluCurImage->Bpc)
{
case 1:
// Calculate new pixel(s)
NewColour[0] = (ILuint)(BytePtr[i * iluCurImage->Bpp] * Scale);
if (Bpp >= 3) {
NewColour[1] = (ILuint)(BytePtr[i * iluCurImage->Bpp + 1] * Scale);
NewColour[2] = (ILuint)(BytePtr[i * iluCurImage->Bpp + 2] * Scale);
}
// Clamp values
if (NewColour[0] > UCHAR_MAX)
NewColour[0] = UCHAR_MAX;
if (Bpp >= 3) {
if (NewColour[1] > UCHAR_MAX)
NewColour[1] = UCHAR_MAX;
if (NewColour[2] > UCHAR_MAX)
NewColour[2] = UCHAR_MAX;
}
// Store pixel(s)
BytePtr[i * iluCurImage->Bpp] = (ILubyte)NewColour[0];
if (Bpp >= 3) {
BytePtr[i * iluCurImage->Bpp + 1] = (ILubyte)NewColour[1];
BytePtr[i * iluCurImage->Bpp + 2] = (ILubyte)NewColour[2];
}
break;
/*case 2:
// Calculate new pixel
NewColour[0] = (ILuint)(ShortPtr[i * iluCurImage->Bpp] * Scale);
NewColour[1] = (ILuint)(ShortPtr[i * iluCurImage->Bpp + 1] * Scale);
NewColour[2] = (ILuint)(ShortPtr[i * iluCurImage->Bpp + 2] * Scale);
// Clamp values
if (NewColour[0] > USHRT_MAX)
NewColour[0] = USHRT_MAX;
if (NewColour[1] > USHRT_MAX)
NewColour[1] = USHRT_MAX;
if (NewColour[2] > USHRT_MAX)
NewColour[2] = USHRT_MAX;
// Store pixel
ShortPtr[i * iluCurImage->Bpp] = (ILushort)NewColour[0];
ShortPtr[i * iluCurImage->Bpp + 1] = (ILushort)NewColour[1];
ShortPtr[i * iluCurImage->Bpp + 2] = (ILushort)NewColour[2];
break;
case 4:
// Calculate new pixel
NewColour[0] = (ILuint)(IntPtr[i * iluCurImage->Bpp] * Scale);
NewColour[1] = (ILuint)(IntPtr[i * iluCurImage->Bpp + 1] * Scale);
NewColour[2] = (ILuint)(IntPtr[i * iluCurImage->Bpp + 2] * Scale);
// Clamp values
if (NewColour[0] > UINT_MAX)
NewColour[0] = UINT_MAX;
if (NewColour[1] > UINT_MAX)
NewColour[1] = UINT_MAX;
if (NewColour[2] > UINT_MAX)
NewColour[2] = UINT_MAX;
// Store pixel
IntPtr[i * 4 * iluCurImage->Bpp] = NewColour[0];
IntPtr[i * 4 * iluCurImage->Bpp + 1] = NewColour[1];
IntPtr[i * 4 * iluCurImage->Bpp + 2] = NewColour[2];
break;*/
}
}
ilCloseImage(LumImage);
return IL_TRUE;
}
+60
View File
@@ -0,0 +1,60 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/21/2009
//
// Filename: src-ILU/src/ilu_mipmap.c
//
// Description: Generates mipmaps for the current image.
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
//#include "ilu_mipmap.h"
//#include "ilu_states.h"
ILboolean iBuildMipmaps(ILimage *Parent, ILuint Width, ILuint Height, ILuint Depth)
{
ILuint x1 = 0, x2 = 0, y1 = 0, y2 = 0;
if (Parent->Width == 1 && Parent->Height == 1 && Parent->Depth == 1) { // Already at the last mipmap
return IL_TRUE;
}
if (Width == 0)
Width = 1;
if (Height == 0)
Height = 1;
if (Depth == 0)
Depth = 1;
Parent->Mipmaps = iluScale_(Parent, Width, Height, Depth);
if (Parent->Mipmaps == NULL)
return IL_FALSE;
iBuildMipmaps(Parent->Mipmaps, Parent->Mipmaps->Width >> 1, Parent->Mipmaps->Height >> 1, Parent->Mipmaps->Depth >> 1);
return IL_TRUE;
}
// Note: No longer changes all textures to powers of 2.
ILboolean ILAPIENTRY iluBuildMipmaps()
{
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
// Get rid of any existing mipmaps.
if (iluCurImage->Mipmaps) {
ilCloseImage(iluCurImage->Mipmaps);
iluCurImage->Mipmaps = NULL;
}
return iBuildMipmaps(iluCurImage, iluCurImage->Width >> 1, iluCurImage->Height >> 1, iluCurImage->Depth >> 1);
}
+225
View File
@@ -0,0 +1,225 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_noise.c
//
// Description: Noise generation functions
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
#include <math.h>
//#include <time.h>
#include <limits.h>
// Very simple right now.
// This will probably use Perlin noise and parameters in the future.
ILboolean ILAPIENTRY iluNoisify(ILclampf Tolerance)
{
ILuint i, j, c, Factor, Factor2, NumPix;
ILint Val;
ILushort *ShortPtr;
ILuint *IntPtr;
ILubyte *RegionMask;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
RegionMask = iScanFill();
// @TODO: Change this to work correctly without time()!
//srand(time(NULL));
NumPix = iluCurImage->SizeOfData / iluCurImage->Bpc;
switch (iluCurImage->Bpc)
{
case 1:
Factor = (ILubyte)(Tolerance * (UCHAR_MAX / 2));
if (Factor == 0)
return IL_TRUE;
Factor2 = Factor + Factor;
for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
if (RegionMask) {
if (!RegionMask[j])
continue;
}
Val = (ILint)((ILint)(rand() % Factor2) - Factor);
for (c = 0; c < iluCurImage->Bpp; c++) {
if ((ILint)iluCurImage->Data[i + c] + Val > UCHAR_MAX)
iluCurImage->Data[i + c] = UCHAR_MAX;
else if ((ILint)iluCurImage->Data[i + c] + Val < 0)
iluCurImage->Data[i + c] = 0;
else
iluCurImage->Data[i + c] += Val;
}
}
break;
case 2:
Factor = (ILushort)(Tolerance * (USHRT_MAX / 2));
if (Factor == 0)
return IL_TRUE;
Factor2 = Factor + Factor;
ShortPtr = (ILushort*)iluCurImage->Data;
for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
if (RegionMask) {
if (!RegionMask[j])
continue;
}
Val = (ILint)((ILint)(rand() % Factor2) - Factor);
for (c = 0; c < iluCurImage->Bpp; c++) {
if ((ILint)ShortPtr[i + c] + Val > USHRT_MAX)
ShortPtr[i + c] = USHRT_MAX;
else if ((ILint)ShortPtr[i + c] + Val < 0)
ShortPtr[i + c] = 0;
else
ShortPtr[i + c] += Val;
}
}
break;
case 4:
Factor = (ILuint)(Tolerance * (UINT_MAX / 2));
if (Factor == 0)
return IL_TRUE;
Factor2 = Factor + Factor;
IntPtr = (ILuint*)iluCurImage->Data;
for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
if (RegionMask) {
if (!RegionMask[j])
continue;
}
Val = (ILint)((ILint)(rand() % Factor2) - Factor);
for (c = 0; c < iluCurImage->Bpp; c++) {
if (IntPtr[i + c] + Val > UINT_MAX)
IntPtr[i + c] = UINT_MAX;
else if ((ILint)IntPtr[i + c] + Val < 0)
IntPtr[i + c] = 0;
else
IntPtr[i + c] += Val;
}
}
break;
}
ifree(RegionMask);
return IL_TRUE;
}
// Information on Perlin Noise taken from
// http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
/*ILdouble Noise(ILint x, ILint y)
{
ILint n;
n = x + y * 57;
n = (n<<13) ^ n;
return (1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
ILdouble SmoothNoise(ILint x, ILint y)
{
ILdouble corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
ILdouble sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8;
ILdouble center = Noise(x, y) / 4;
return corners + sides + center;
}
ILdouble Interpolate(ILdouble a, ILdouble b, ILdouble x)
{
ILdouble ft = x * 3.1415927;
ILdouble f = (1 - cos(ft)) * .5;
return a*(1-f) + b*f;
}
ILdouble InterpolatedNoise(ILdouble x, ILdouble y)
{
ILint integer_X, integer_Y;
ILdouble fractional_X, fractional_Y, v1, v2, v3, v4, i1, i2;
integer_X = (ILint)x;
fractional_X = x - integer_X;
integer_Y = (ILint)y;
fractional_Y = y - integer_Y;
v1 = SmoothNoise(integer_X, integer_Y);
v2 = SmoothNoise(integer_X + 1, integer_Y);
v3 = SmoothNoise(integer_X, integer_Y + 1);
v4 = SmoothNoise(integer_X + 1, integer_Y + 1);
i1 = Interpolate(v1, v2, fractional_X);
i2 = Interpolate(v3, v4, fractional_X);
return Interpolate(i1, i2, fractional_Y);
}
ILdouble PerlinNoise(ILdouble x, ILdouble y)
{
ILuint i, n;
ILdouble total = 0, p, frequency, amplitude;
//p = persistence;
//n = Number_Of_Octaves - 1;
n = 2;
//p = .5;
p = (ILdouble)(rand() % 1000) / 1000.0;
for (i = 0; i < n; i++) {
frequency = pow(2, i);
amplitude = pow(p, i);
total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
}
return total;
}
ILboolean ILAPIENTRY iluNoisify()
{
ILuint x, y, c;
ILint Val;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
for (y = 0; y < iluCurImage->Height; y++) {
for (x = 0; x < iluCurImage->Width; x++) {
Val = (ILint)(PerlinNoise(x, y) * 50.0);
for (c = 0; c < iluCurImage->Bpp; c++) {
if ((ILint)iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] + Val > 255)
iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] = 255;
else if ((ILint)iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] + Val < 0)
iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] = 0;
else
iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] += Val;
}
}
}
return IL_TRUE;
}*/
+304
View File
@@ -0,0 +1,304 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 07/09/2002 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_region.c
//
// Description: Creates an image region.
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
#include "ilu_region.h"
ILpointi *RegionPointsi = NULL;
ILpointf *RegionPointsf = NULL;
ILuint PointNum = 0;
ILubyte *iRegionMask = NULL;
void ILAPIENTRY iluRegionfv(ILpointf *Points, ILuint n)
{
if (Points == NULL || n == 0) {
ifree(RegionPointsi);
ifree(RegionPointsf);
RegionPointsf = NULL;
PointNum = 0;
return;
}
if (n < 3) {
ilSetError(ILU_INVALID_PARAM);
return;
}
ifree(RegionPointsi);
ifree(RegionPointsf);
RegionPointsf = (ILpointf*)ialloc(sizeof(ILpointf) * n);
if (RegionPointsf == NULL)
return;
memcpy(RegionPointsf, Points, sizeof(ILpointi) * n);
PointNum = n;
return;
}
void ILAPIENTRY iluRegioniv(ILpointi *Points, ILuint n)
{
if (Points == NULL || n == 0) {
ifree(RegionPointsi);
ifree(RegionPointsf);
RegionPointsi = NULL;
PointNum = 0;
return;
}
if (n < 3) {
ilSetError(ILU_INVALID_PARAM);
return;
}
ifree(RegionPointsi);
ifree(RegionPointsf);
RegionPointsi = (ILpointi*)ialloc(sizeof(ILpointi) * n);
if (RegionPointsi == NULL)
return;
memcpy(RegionPointsi, Points, sizeof(ILpointi) * n);
PointNum = n;
return;
}
// Inserts edge into list in order of increasing xIntersect field.
void InsertEdge(Edge *list, Edge *edge)
{
Edge *p, *q = list;
p = q->next;
while (p != NULL) {
if (edge->xIntersect < p->xIntersect) {
p = NULL;
}
else {
q = p;
p = p->next;
}
}
edge->next = q->next;
q->next = edge;
}
// For an index, return y-coordinate of next nonhorizontal line
ILint yNext(ILint k, ILint cnt, ILpointi *pts)
{
ILint j;
if ((k+1) > (cnt-1))
j = 0;
else
j = k + 1;
while (pts[k].y == pts[j].y) {
if ((j+1) > (cnt-1))
j = 0;
else
j++;
}
return pts[j].y;
}
// Store lower-y coordinate and inverse slope for each edge. Adjust
// and store upper-y coordinate for edges that are the lower member
// of a monotonically increasing or decreasing pair of edges
void MakeEdgeRec(ILpointi lower, ILpointi upper, ILint yComp, Edge *edge, Edge *edges[])
{
edge->dxPerScan = (ILfloat)(upper.x - lower.x) / (upper.y - lower.y);
edge->xIntersect = (ILfloat)lower.x;
if (upper.y < yComp)
edge->yUpper = upper.y - 1;
else
edge->yUpper = upper.y;
InsertEdge(edges[lower.y], edge);
}
void BuildEdgeList(ILuint cnt, ILpointi *pts, Edge **edges)
{
Edge *edge;
ILpointi v1, v2;
ILuint i;
ILint yPrev = pts[cnt - 2].y;
v1.x = pts[cnt-1].x;
v1.y = pts[cnt-1].y;
for (i = 0; i < cnt; i++) {
v2 = pts[i];
if (v1.y != v2.y) { // nonhorizontal line
edge = (Edge*)ialloc(sizeof(Edge));
if (v1.y < v2.y) { // up-going edge
MakeEdgeRec(v1, v2, yNext(i, cnt, pts), edge, edges);
}
else { // down-going edge
MakeEdgeRec(v2, v1, yPrev, edge, edges);
}
}
yPrev = v1.y;
v1 = v2;
}
}
void BuildActiveList(ILint scan, Edge *active, Edge *edges[])
{
Edge *p, *q;
p = edges[scan]->next;
while (p) {
q = p->next;
InsertEdge(active, p);
p = q;
}
}
#define iRegionSetPixel(x,y) (iRegionMask[y * iluCurImage->Width + x] = 1 )
void FillScan(ILint scan, Edge *active)
{
Edge *p1, *p2;
ILint i;
p1 = active->next;
while (p1) {
p2 = p1->next;
for (i = (ILuint)p1->xIntersect; i < p2->xIntersect; i++) {
iRegionSetPixel((ILuint)i, scan);
}
p1 = p2->next;
}
}
void DeleteAfter(Edge *q)
{
Edge *p = q->next;
q->next = p->next;
free(p);
}
// Delete completed edges. Update 'xIntersect' field for others
void UpdateActiveList(ILint scan, Edge *active)
{
Edge *q = active, *p = active->next;
while (p) {
if (scan >= p->yUpper) {
p = p->next;
DeleteAfter(q);
}
else {
p->xIntersect = p->xIntersect + p->dxPerScan;
q = p;
p = p->next;
}
}
}
void ResortActiveList(Edge *active)
{
Edge *q, *p = active->next;
active->next = NULL;
while (p) {
q = p->next;
InsertEdge(active, p);
p = q;
}
}
ILubyte *iScanFill()
{
Edge **edges = NULL, *active = NULL/*, *temp*/;
ILuint i, scan;
iRegionMask = NULL;
if ((RegionPointsi == NULL && RegionPointsf == NULL) || PointNum == 0)
return NULL;
if (RegionPointsf) {
RegionPointsi = (ILpointi*)ialloc(sizeof(ILpointi) * PointNum);
if (RegionPointsi == NULL)
goto error;
}
for (i = 0; i < PointNum; i++) {
if (RegionPointsf) {
RegionPointsi[i].x = (ILuint)(iluCurImage->Width * RegionPointsf[i].x);
RegionPointsi[i].y = (ILuint)(iluCurImage->Height * RegionPointsf[i].y);
}
if (RegionPointsi[i].x >= (ILint)iluCurImage->Width || RegionPointsi[i].y >= (ILint)iluCurImage->Height)
goto error;
}
edges = (Edge**)ialloc(sizeof(Edge*) * iluCurImage->Height);
iRegionMask = (ILubyte*)ialloc(iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth);
if (edges == NULL || iRegionMask == NULL)
goto error;
imemclear(iRegionMask, iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth);
for (i = 0; i < iluCurImage->Height; i++) {
edges[i] = (Edge*)ialloc(sizeof(Edge));
edges[i]->next = NULL;
}
BuildEdgeList(PointNum, RegionPointsi, edges);
active = (Edge*)ialloc(sizeof(Edge));
active->next = NULL;
for (scan = 0; scan < iluCurImage->Height; scan++) {
BuildActiveList(scan, active, edges);
if (active->next) {
FillScan(scan, active);
UpdateActiveList(scan, active);
ResortActiveList(active);
}
}
// Free edge records that have been allocated.
/*for (i = 0; i < iluCurImage->Height; i++) {
while (edges[i]) {
temp = edges[i]->next;
ifree(edges[i]);
edges[i] = temp;
}
}*/
ifree(edges);
if (RegionPointsf) {
ifree(RegionPointsi);
RegionPointsi = NULL;
}
return iRegionMask;
error:
if (RegionPointsf) {
ifree(RegionPointsi);
RegionPointsi = NULL;
}
// Free edge records that have been allocated.
ifree(edges);
ifree(iRegionMask);
return NULL;
}
+369
View File
@@ -0,0 +1,369 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2002 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_rotate.c
//
// Description: Rotates an image.
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
#include "ilu_states.h"
ILboolean ILAPIENTRY iluRotate(ILfloat Angle)
{
ILimage *Temp, *Temp1, *CurImage = NULL;
ILenum PalType = 0;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (iluCurImage->Format == IL_COLOUR_INDEX) {
PalType = iluCurImage->Pal.PalType;
CurImage = iluCurImage;
iluCurImage = iConvertImage(iluCurImage, ilGetPalBaseType(CurImage->Pal.PalType), IL_UNSIGNED_BYTE);
}
Temp = iluRotate_(iluCurImage, Angle);
if (Temp != NULL) {
if (PalType != 0) {
ilCloseImage(iluCurImage);
Temp1 = iConvertImage(Temp, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
ilCloseImage(Temp);
Temp = Temp1;
ilSetCurImage(CurImage);
}
ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data);
if (PalType != 0) {
iluCurImage = ilGetCurImage();
iluCurImage->Pal.PalSize = Temp->Pal.PalSize;
iluCurImage->Pal.PalType = Temp->Pal.PalType;
iluCurImage->Pal.Palette = (ILubyte*)ialloc(Temp->Pal.PalSize);
if (iluCurImage->Pal.Palette == NULL) {
ilCloseImage(Temp);
return IL_FALSE;
}
memcpy(iluCurImage->Pal.Palette, Temp->Pal.Palette, Temp->Pal.PalSize);
}
iluCurImage->Origin = Temp->Origin;
ilCloseImage(Temp);
return IL_TRUE;
}
return IL_FALSE;
}
ILboolean ILAPIENTRY iluRotate3D(ILfloat x, ILfloat y, ILfloat z, ILfloat Angle)
{
ILimage *Temp;
// return IL_FALSE;
iluCurImage = ilGetCurImage();
Temp = iluRotate3D_(iluCurImage, x, y, z, Angle);
if (Temp != NULL) {
ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data);
iluCurImage->Origin = Temp->Origin;
ilSetPal(&Temp->Pal);
ilCloseImage(Temp);
return IL_TRUE;
}
return IL_FALSE;
}
//! Rotates a bitmap any angle.
// Code help comes from http://www.leunen.com/cbuilder/rotbmp.html.
ILAPI ILimage* ILAPIENTRY iluRotate_(ILimage *Image, ILfloat Angle)
{
ILimage *Rotated = NULL;
ILint x, y, c;
ILdouble Cos, Sin;
ILuint RotOffset, ImgOffset;
ILint MinX, MinY, MaxX, MaxY;
ILushort *ShortPtr;
ILuint *IntPtr;
ILdouble *DblPtr;
ILdouble Point1x, Point1y, Point2x, Point2y, Point3x, Point3y;
ILint SrcX, SrcY;
// Multiples of 90 are special.
Angle = (ILfloat)fmod((ILdouble)Angle, 360.0);
if (Angle < 0)
Angle = 360.0f + Angle;
Cos = (ILdouble)cos((IL_PI * Angle) / 180.0);
Sin = (ILdouble)sin((IL_PI * Angle) / 180.0);
Point1x = (-(ILint)Image->Height * Sin);
Point1y = (Image->Height * Cos);
Point2x = (Image->Width * Cos - Image->Height * Sin);
Point2y = (Image->Height * Cos + Image->Width * Sin);
Point3x = (Image->Width * Cos);
Point3y = (Image->Width * Sin);
MinX = (ILint)IL_MIN(0, IL_MIN(Point1x, IL_MIN(Point2x, Point3x)));
MinY = (ILint)IL_MIN(0, IL_MIN(Point1y, IL_MIN(Point2y, Point3y)));
MaxX = (ILint)IL_MAX(Point1x, IL_MAX(Point2x, Point3x));
MaxY = (ILint)IL_MAX(Point1y, IL_MAX(Point2y, Point3y));
Rotated = (ILimage*)icalloc(1, sizeof(ILimage));
if (Rotated == NULL)
return NULL;
if (ilCopyImageAttr(Rotated, Image) == IL_FALSE) {
ilCloseImage(Rotated);
return NULL;
}
if (ilResizeImage(Rotated, (ILuint)ceil(fabs(MaxX) - MinX), (ILuint)ceil(fabs(MaxY) - MinY), 1, Image->Bpp, Image->Bpc) == IL_FALSE) {
ilCloseImage(Rotated);
return IL_FALSE;
}
ilClearImage_(Rotated);
ShortPtr = (ILushort*)iluCurImage->Data;
IntPtr = (ILuint*)iluCurImage->Data;
DblPtr = (ILdouble*)iluCurImage->Data;
//if (iluFilter == ILU_NEAREST) {
switch (iluCurImage->Bpc)
{
case 1: // Byte-based (most images)
if (Angle == 90.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = x * Rotated->Bps + (Image->Width - 1 - y) * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
Rotated->Data[RotOffset + c] = Image->Data[ImgOffset + c];
}
}
}
}
else if (Angle == 180.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = (Image->Height - 1 - y) * Rotated->Bps + x * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
Rotated->Data[RotOffset + c] = Image->Data[ImgOffset + c];
}
}
}
}
else if (Angle == 270.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = (Image->Height - 1 - x) * Rotated->Bps + y * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
Rotated->Data[RotOffset + c] = Image->Data[ImgOffset + c];
}
}
}
}
else {
for (x = 0; x < (ILint)Rotated->Width; x++) {
for (y = 0; y < (ILint)Rotated->Height; y++) {
SrcX = (ILint)((x + MinX) * Cos + (y + MinY) * Sin);
SrcY = (ILint)((y + MinY) * Cos - (x + MinX) * Sin);
if (SrcX >= 0 && SrcX < (ILint)Image->Width && SrcY >= 0 && SrcY < (ILint)Image->Height) {
RotOffset = y * Rotated->Bps + x * Rotated->Bpp;
ImgOffset = (ILuint)SrcY * Image->Bps + (ILuint)SrcX * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
Rotated->Data[RotOffset + c] = Image->Data[ImgOffset + c];
}
}
}
}
}
break;
case 2: // Short-based
Image->Bps /= 2; // Makes it easier to just
Rotated->Bps /= 2; // cast to short.
if (Angle == 90.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = x * Rotated->Bps + (Image->Width - 1 - y) * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILushort*)(Rotated->Data))[RotOffset + c] = ShortPtr[ImgOffset + c];
}
}
}
}
else if (Angle == 180.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = (Image->Height - 1 - y) * Rotated->Bps + x * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILushort*)(Rotated->Data))[RotOffset + c] = ShortPtr[ImgOffset + c];
}
}
}
}
else if (Angle == 270.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = (Image->Height - 1 - x) * Rotated->Bps + y * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILushort*)(Rotated->Data))[RotOffset + c] = ShortPtr[ImgOffset + c];
}
}
}
}
else {
for (x = 0; x < (ILint)Rotated->Width; x++) {
for (y = 0; y < (ILint)Rotated->Height; y++) {
SrcX = (ILint)((x + MinX) * Cos + (y + MinY) * Sin);
SrcY = (ILint)((y + MinY) * Cos - (x + MinX) * Sin);
if (SrcX >= 0 && SrcX < (ILint)Image->Width && SrcY >= 0 && SrcY < (ILint)Image->Height) {
RotOffset = y * Rotated->Bps + x * Rotated->Bpp;
ImgOffset = (ILuint)SrcY * Image->Bps + (ILuint)SrcX * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILushort*)(Rotated->Data))[RotOffset + c] = ShortPtr[ImgOffset + c];
}
}
}
}
}
Image->Bps *= 2;
Rotated->Bps *= 2;
break;
case 4: // Floats or 32-bit integers
Image->Bps /= 4;
Rotated->Bps /= 4;
if (Angle == 90.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = x * Rotated->Bps + (Image->Width - 1 - y) * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILuint*)(Rotated->Data))[RotOffset + c] = IntPtr[ImgOffset + c];
}
}
}
}
else if (Angle == 180.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = (Image->Height - 1 - y) * Rotated->Bps + x * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILuint*)(Rotated->Data))[RotOffset + c] = IntPtr[ImgOffset + c];
}
}
}
}
else if (Angle == 270.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = (Image->Height - 1 - x) * Rotated->Bps + y * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILuint*)(Rotated->Data))[RotOffset + c] = IntPtr[ImgOffset + c];
}
}
}
}
else {
for (x = 0; x < (ILint)Rotated->Width; x++) {
for (y = 0; y < (ILint)Rotated->Height; y++) {
SrcX = (ILint)((x + MinX) * Cos + (y + MinY) * Sin);
SrcY = (ILint)((y + MinY) * Cos - (x + MinX) * Sin);
if (SrcX >= 0 && SrcX < (ILint)Image->Width && SrcY >= 0 && SrcY < (ILint)Image->Height) {
RotOffset = y * Rotated->Bps + x * Rotated->Bpp;
ImgOffset = (ILuint)SrcY * Image->Bps + (ILuint)SrcX * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILuint*)(Rotated->Data))[RotOffset + c] = IntPtr[ImgOffset + c];
}
}
}
}
}
Image->Bps *= 4;
Rotated->Bps *= 4;
break;
case 8: // Double or 64-bit integers
Image->Bps /= 8;
Rotated->Bps /= 8;
if (Angle == 90.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = x * Rotated->Bps + (Image->Width - 1 - y) * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILdouble*)(Rotated->Data))[RotOffset + c] = DblPtr[ImgOffset + c];
}
}
}
}
else if (Angle == 180.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = (Image->Height - 1 - y) * Rotated->Bps + x * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILdouble*)(Rotated->Data))[RotOffset + c] = DblPtr[ImgOffset + c];
}
}
}
}
else if (Angle == 270.0) {
for (x = 0; x < (ILint)Image->Width; x++) {
for (y = 0; y < (ILint)Image->Height; y++) {
RotOffset = (Image->Height - 1 - x) * Rotated->Bps + y * Rotated->Bpp;
ImgOffset = y * Image->Bps + x * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILdouble*)(Rotated->Data))[RotOffset + c] = DblPtr[ImgOffset + c];
}
}
}
}
else {
for (x = 0; x < (ILint)Rotated->Width; x++) {
for (y = 0; y < (ILint)Rotated->Height; y++) {
SrcX = (ILint)((x + MinX) * Cos + (y + MinY) * Sin);
SrcY = (ILint)((y + MinY) * Cos - (x + MinX) * Sin);
if (SrcX >= 0 && SrcX < (ILint)Image->Width && SrcY >= 0 && SrcY < (ILint)Image->Height) {
RotOffset = y * Rotated->Bps + x * Rotated->Bpp;
ImgOffset = (ILuint)SrcY * Image->Bps + (ILuint)SrcX * Image->Bpp;
for (c = 0; c < Rotated->Bpp; c++) {
((ILdouble*)(Rotated->Data))[RotOffset + c] = DblPtr[ImgOffset + c];
}
}
}
}
}
Image->Bps *= 8;
Rotated->Bps *= 8;
break;
}
return Rotated;
}
ILAPI ILimage* ILAPIENTRY iluRotate3D_(ILimage *Image, ILfloat x, ILfloat y, ILfloat z, ILfloat Angle)
{
Image; x; y; z; Angle;
return NULL;
}
+307
View File
@@ -0,0 +1,307 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 12/27/2008
//
// Filename: src-ILU/src/ilu_scale.c
//
// Description: Scales an image.
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
#include "ilu_states.h"
ILboolean ILAPIENTRY iluEnlargeImage(ILfloat XDim, ILfloat YDim, ILfloat ZDim)
{
if (XDim <= 0.0f || YDim <= 0.0f || ZDim <= 0.0f) {
ilSetError(ILU_INVALID_PARAM);
return IL_FALSE;
}
iluCurImage = ilGetCurImage();
return iluScale((ILuint)(iluCurImage->Width * XDim), (ILuint)(iluCurImage->Height * YDim),
(ILuint)(iluCurImage->Depth * ZDim));
}
ILimage *iluScale1D_(ILimage *Image, ILimage *Scaled, ILuint Width);
ILimage *iluScale2D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
ILimage *iluScale3D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth);
ILboolean ILAPIENTRY iluScale(ILuint Width, ILuint Height, ILuint Depth)
{
ILimage *Temp;
ILboolean UsePal;
ILenum PalType;
ILenum Origin;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (iluCurImage->Width == Width && iluCurImage->Height == Height && iluCurImage->Depth == Depth)
return IL_TRUE;
// A parameter of 0 is not valid. Let's just assume that the user wanted a value of 1 instead.
if (Width == 0) Width = 1;
if (Height == 0) Height = 1;
if (Depth == 0) Depth = 1;
if ((iluCurImage->Width<Width) || (iluCurImage->Height<Height)) // only do special scale if there is some zoom?
{
switch (iluFilter)
{
case ILU_SCALE_BOX:
case ILU_SCALE_TRIANGLE:
case ILU_SCALE_BELL:
case ILU_SCALE_BSPLINE:
case ILU_SCALE_LANCZOS3:
case ILU_SCALE_MITCHELL:
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
// Not supported yet.
if (iluCurImage->Type != IL_UNSIGNED_BYTE ||
iluCurImage->Format == IL_COLOUR_INDEX ||
iluCurImage->Depth > 1) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (iluCurImage->Width > Width) // shrink width first
{
Origin = iluCurImage->Origin;
Temp = iluScale_(iluCurImage, Width, iluCurImage->Height, iluCurImage->Depth);
if (Temp != NULL) {
if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
ilCloseImage(Temp);
return IL_FALSE;
}
iluCurImage->Origin = Origin;
ilCloseImage(Temp);
}
}
else if (iluCurImage->Height > Height) // shrink height first
{
Origin = iluCurImage->Origin;
Temp = iluScale_(iluCurImage, iluCurImage->Width, Height, iluCurImage->Depth);
if (Temp != NULL) {
if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
ilCloseImage(Temp);
return IL_FALSE;
}
iluCurImage->Origin = Origin;
ilCloseImage(Temp);
}
}
return (ILboolean)iluScaleAdvanced(Width, Height, iluFilter);
}
}
Origin = iluCurImage->Origin;
UsePal = (iluCurImage->Format == IL_COLOUR_INDEX);
PalType = iluCurImage->Pal.PalType;
Temp = iluScale_(iluCurImage, Width, Height, Depth);
if (Temp != NULL) {
if (!ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data)) {
ilCloseImage(Temp);
return IL_FALSE;
}
iluCurImage->Origin = Origin;
ilCloseImage(Temp);
if (UsePal) {
if (!ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE))
return IL_FALSE;
ilConvertPal(PalType);
}
return IL_TRUE;
}
return IL_FALSE;
}
ILAPI ILimage* ILAPIENTRY iluScale_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth)
{
ILimage *Scaled, *CurImage, *ToScale;
ILenum Format, PalType;
CurImage = ilGetCurImage();
Format = Image->Format;
if (Format == IL_COLOUR_INDEX) {
ilSetCurImage(Image);
PalType = Image->Pal.PalType;
ToScale = iConvertImage(iluCurImage, ilGetPalBaseType(Image->Pal.PalType), iluCurImage->Type);
}
else {
ToScale = Image;
}
// So we don't replicate this 3 times (one in each iluScalexD_() function.
Scaled = (ILimage*)icalloc(1, sizeof(ILimage));
if (ilCopyImageAttr(Scaled, ToScale) == IL_FALSE) {
ilCloseImage(Scaled);
if (ToScale != Image)
ilCloseImage(ToScale);
ilSetCurImage(CurImage);
return NULL;
}
if (ilResizeImage(Scaled, Width, Height, Depth, ToScale->Bpp, ToScale->Bpc) == IL_FALSE) {
ilCloseImage(Scaled);
if (ToScale != Image)
ilCloseImage(ToScale);
ilSetCurImage(CurImage);
return NULL;
}
if (Height <= 1 && Image->Height <= 1) {
iluScale1D_(ToScale, Scaled, Width);
}
if (Depth <= 1 && Image->Depth <= 1) {
iluScale2D_(ToScale, Scaled, Width, Height);
}
else {
iluScale3D_(ToScale, Scaled, Width, Height, Depth);
}
if (Format == IL_COLOUR_INDEX) {
//ilSetCurImage(Scaled);
//ilConvertImage(IL_COLOUR_INDEX);
ilSetCurImage(CurImage);
ilCloseImage(ToScale);
}
return Scaled;
}
ILimage *iluScale1D_(ILimage *Image, ILimage *Scaled, ILuint Width)
{
ILuint x1, x2;
ILuint NewX1, NewX2, NewX3, x, c;
ILdouble ScaleX, t1, t2, f;
ILushort *ShortPtr, *SShortPtr;
ILuint *IntPtr, *SIntPtr;
if (Image == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
ScaleX = (ILdouble)Width / Image->Width;
ShortPtr = (ILushort*)Image->Data;
SShortPtr = (ILushort*)Scaled->Data;
IntPtr = (ILuint*)Image->Data;
SIntPtr = (ILuint*)Scaled->Data;
if (iluFilter == ILU_NEAREST) {
switch (Image->Bpc)
{
case 1:
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
Scaled->Data[NewX1 + c] = Image->Data[NewX2 + c];
}
}
break;
case 2:
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SShortPtr[NewX1 + c] = ShortPtr[NewX2 + c];
}
}
break;
case 4:
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SIntPtr[NewX1 + c] = IntPtr[NewX2 + c];
}
}
break;
}
}
else { // IL_LINEAR or IL_BILINEAR
switch (Image->Bpc)
{
case 1:
NewX3 = 0;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t2 = t1 * Width - (ILuint)(t1 * Width);
f = (1.0 - cos(t2 * IL_PI)) * .5;
NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = Image->Data[NewX1 + c];
x2 = Image->Data[NewX2 + c];
Scaled->Data[NewX3 + c] = (ILubyte)(x1 * (1.0 - f) + x2 * f);
}
NewX3 += Scaled->Bpp;
}
break;
case 2:
NewX3 = 0;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t2 = t1 * Width - (ILuint)(t1 * Width);
f = (1.0 - cos(t2 * IL_PI)) * .5;
NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = ShortPtr[NewX1 + c];
x2 = ShortPtr[NewX2 + c];
SShortPtr[NewX3 + c] = (ILushort)(x1 * (1.0 - f) + x2 * f);
}
NewX3 += Scaled->Bpp;
}
break;
case 4:
NewX3 = 0;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t2 = t1 * Width - (ILuint)(t1 * Width);
f = (1.0 - cos(t2 * IL_PI)) * .5;
NewX1 = ((ILuint)(t1 * Width / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t1 * Width / ScaleX) + 1) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = IntPtr[NewX1 + c];
x2 = IntPtr[NewX2 + c];
SIntPtr[NewX3 + c] = (ILuint)(x1 * (1.0 - f) + x2 * f);
}
NewX3 += Scaled->Bpp;
}
break;
}
}
return Scaled;
}
+479
View File
@@ -0,0 +1,479 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_scale2d.c
//
// Description: Scales an image.
//
//-----------------------------------------------------------------------------
// NOTE: Don't look at this file if you wish to preserve your sanity!
#include "ilu_internal.h"
#include "ilu_states.h"
ILimage *iluScale2DNear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
ILimage *iluScale2DLinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
ILimage *iluScale2DBilinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height);
static ILuint x1, x2;
static ILuint NewY1, NewY2, NewX1, NewX2, Size, x, y, c;
static ILdouble ScaleX, ScaleY, t1, t2, t3, t4, f, ft, NewX;
static ILdouble Table[2][4]; // Assumes we don't have larger than 32-bit images.
static ILuint ImgBps, SclBps;
static ILushort *ShortPtr, *SShortPtr;
static ILuint *IntPtr, *SIntPtr;
static ILfloat *FloatPtr, *SFloatPtr;
ILimage *iluScale2D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height)
{
if (Image == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
ScaleX = (ILfloat)Width / Image->Width;
ScaleY = (ILfloat)Height / Image->Height;
if (iluFilter == ILU_NEAREST)
return iluScale2DNear_(Image, Scaled, Width, Height);
else if (iluFilter == ILU_LINEAR)
return iluScale2DLinear_(Image, Scaled, Width, Height);
// iluFilter == ILU_BILINEAR
return iluScale2DBilinear_(Image, Scaled, Width, Height);
}
ILimage *iluScale2DNear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height)
{
ImgBps = Image->Bps / Image->Bpc;
SclBps = Scaled->Bps / Scaled->Bpc;
switch (Image->Bpc)
{
case 1:
for (y = 0; y < Height; y++) {
NewY1 = y * SclBps;
NewY2 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
Scaled->Data[NewY1 + NewX1 + c] = Image->Data[NewY2 + NewX2 + c];
x1 = 0;
}
}
}
break;
case 2:
ShortPtr = (ILushort*)Image->Data;
SShortPtr = (ILushort*)Scaled->Data;
for (y = 0; y < Height; y++) {
NewY1 = y * SclBps;
NewY2 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SShortPtr[NewY1 + NewX1 + c] = ShortPtr[NewY2 + NewX2 + c];
x1 = 0;
}
}
}
break;
case 4:
IntPtr = (ILuint*)Image->Data;
SIntPtr = (ILuint*)Scaled->Data;
for (y = 0; y < Height; y++) {
NewY1 = y * SclBps;
NewY2 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SIntPtr[NewY1 + NewX1 + c] = IntPtr[NewY2 + NewX2 + c];
x1 = 0;
}
}
}
break;
}
return Scaled;
}
ILimage *iluScale2DLinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height)
{
ImgBps = Image->Bps / Image->Bpc;
SclBps = Scaled->Bps / Scaled->Bpc;
switch (Image->Bpc)
{
case 1:
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
ft = t2 * IL_PI;
f = (1.0 - cos(ft)) * .5;
NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
Size = y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = Image->Data[NewY1 + NewX1 + c];
x2 = Image->Data[NewY1 + NewX2 + c];
Scaled->Data[Size + c] = (ILubyte)((1.0 - f) * x1 + f * x2);
}
}
}
break;
case 2:
ShortPtr = (ILushort*)Image->Data;
SShortPtr = (ILushort*)Scaled->Data;
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
ft = t2 * IL_PI;
f = (1.0 - cos(ft)) * .5;
NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
Size = y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = ShortPtr[NewY1 + NewX1 + c];
x2 = ShortPtr[NewY1 + NewX2 + c];
SShortPtr[Size + c] = (ILushort)((1.0 - f) * x1 + f * x2);
}
}
}
break;
case 4:
IntPtr = (ILuint*)Image->Data;
SIntPtr = (ILuint*)Scaled->Data;
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
ft = t2 * IL_PI;
f = (1.0 - cos(ft)) * .5;
NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
Size = y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = IntPtr[NewY1 + NewX1 + c];
x2 = IntPtr[NewY1 + NewX2 + c];
SIntPtr[Size + c] = (ILuint)((1.0 - f) * x1 + f * x2);
}
}
}
break;
}
return Scaled;
}
// Rewrote using an algorithm described by Paul Nettle at
// http://www.gamedev.net/reference/articles/article669.asp.
ILimage *iluScale2DBilinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height)
{
ILfloat ul, ll, ur, lr;
ILfloat FracX, FracY;
ILfloat SrcX, SrcY;
ILuint iSrcX, iSrcY, iSrcXPlus1, iSrcYPlus1, ulOff, llOff, urOff, lrOff;
ImgBps = Image->Bps / Image->Bpc;
SclBps = Scaled->Bps / Scaled->Bpc;
switch (Image->Bpc)
{
case 1:
for (y = 0; y < Height; y++) {
for (x = 0; x < Width; x++) {
// Calculate where we want to choose pixels from in our source image.
SrcX = (ILfloat)x / (ILfloat)ScaleX;
SrcY = (ILfloat)y / (ILfloat)ScaleY;
// Integer part of SrcX and SrcY
iSrcX = (ILuint)floor(SrcX);
iSrcY = (ILuint)floor(SrcY);
// Fractional part of SrcX and SrcY
FracX = SrcX - (ILfloat)(iSrcX);
FracY = SrcY - (ILfloat)(iSrcY);
// We do not want to go past the right edge of the image or past the last line in the image,
// so this takes care of that. Normally, iSrcXPlus1 is iSrcX + 1, but if this is past the
// right side, we have to bring it back to iSrcX. The same goes for iSrcYPlus1.
if (iSrcX < Image->Width - 1)
iSrcXPlus1 = iSrcX + 1;
else
iSrcXPlus1 = iSrcX;
if (iSrcY < Image->Height - 1)
iSrcYPlus1 = iSrcY + 1;
else
iSrcYPlus1 = iSrcY;
// Find out how much we want each of the four pixels contributing to the final values.
ul = (1.0f - FracX) * (1.0f - FracY);
ll = (1.0f - FracX) * FracY;
ur = FracX * (1.0f - FracY);
lr = FracX * FracY;
for (c = 0; c < Scaled->Bpp; c++) {
// We just calculate the offsets for each pixel here...
ulOff = iSrcY * Image->Bps + iSrcX * Image->Bpp + c;
llOff = iSrcYPlus1 * Image->Bps + iSrcX * Image->Bpp + c;
urOff = iSrcY * Image->Bps + iSrcXPlus1 * Image->Bpp + c;
lrOff = iSrcYPlus1 * Image->Bps + iSrcXPlus1 * Image->Bpp + c;
// ...and then we do the actual interpolation here.
Scaled->Data[y * Scaled->Bps + x * Scaled->Bpp + c] = (ILubyte)(
ul * Image->Data[ulOff] + ll * Image->Data[llOff] + ur * Image->Data[urOff] + lr * Image->Data[lrOff]);
}
}
}
break;
case 2:
ShortPtr = (ILushort*)Image->Data;
SShortPtr = (ILushort*)Scaled->Data;
Height--; // Only use regular Height once in the following loop.
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
NewY2 = (ILuint)((y+1) / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX = Width / ScaleX;
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
t3 = (1.0 - t2);
t4 = t1 * NewX;
NewX1 = (ILuint)(t4) * Image->Bpp;
NewX2 = (ILuint)(t4 + 1) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
Table[0][c] = t3 * ShortPtr[NewY1 + NewX1 + c] +
t2 * ShortPtr[NewY1 + NewX2 + c];
Table[1][c] = t3 * ShortPtr[NewY2 + NewX1 + c] +
t2 * ShortPtr[NewY2 + NewX2 + c];
}
// Linearly interpolate between the table values.
t1 = y / (ILdouble)(Height + 1); // Height+1 is the real height now.
t3 = (1.0 - t1);
Size = y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SShortPtr[Size + c] =
(ILushort)(t3 * Table[0][c] + t1 * Table[1][c]);
}
}
}
// Calculate the last row.
NewY1 = (ILuint)(Height / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX = Width / ScaleX;
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
ft = (t4 - (ILuint)(t4)) * IL_PI;
f = (1.0 - cos(ft)) * .5; // Cosine interpolation
NewX1 = (ILuint)(t1 * NewX) * Image->Bpp;
NewX2 = (ILuint)(t1 * NewX + 1) * Image->Bpp;
Size = Height * SclBps + x * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SShortPtr[Size + c] = (ILushort)((1.0 - f) * ShortPtr[NewY1 + NewX1 + c] +
f * ShortPtr[NewY1 + NewX2 + c]);
}
}
break;
case 4:
if (Image->Type != IL_FLOAT) {
IntPtr = (ILuint*)Image->Data;
SIntPtr = (ILuint*)Scaled->Data;
Height--; // Only use regular Height once in the following loop.
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
NewY2 = (ILuint)((y+1) / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX = Width / ScaleX;
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
t3 = (1.0 - t2);
t4 = t1 * NewX;
NewX1 = (ILuint)(t4) * Image->Bpp;
NewX2 = (ILuint)(t4 + 1) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
Table[0][c] = t3 * IntPtr[NewY1 + NewX1 + c] +
t2 * IntPtr[NewY1 + NewX2 + c];
Table[1][c] = t3 * IntPtr[NewY2 + NewX1 + c] +
t2 * IntPtr[NewY2 + NewX2 + c];
}
// Linearly interpolate between the table values.
t1 = y / (ILdouble)(Height + 1); // Height+1 is the real height now.
t3 = (1.0 - t1);
Size = y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SIntPtr[Size + c] =
(ILuint)(t3 * Table[0][c] + t1 * Table[1][c]);
}
}
}
// Calculate the last row.
NewY1 = (ILuint)(Height / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX = Width / ScaleX;
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
ft = (t4 - (ILuint)(t4)) * IL_PI;
f = (1.0 - cos(ft)) * .5; // Cosine interpolation
NewX1 = (ILuint)(t1 * NewX) * Image->Bpp;
NewX2 = (ILuint)(t1 * NewX + 1) * Image->Bpp;
Size = Height * SclBps + x * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SIntPtr[Size + c] = (ILuint)((1.0 - f) * IntPtr[NewY1 + NewX1 + c] +
f * IntPtr[NewY1 + NewX2 + c]);
}
}
}
else { // IL_FLOAT
FloatPtr = (ILfloat*)Image->Data;
SFloatPtr = (ILfloat*)Scaled->Data;
Height--; // Only use regular Height once in the following loop.
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
NewY2 = (ILuint)((y+1) / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX = Width / ScaleX;
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
t3 = (1.0 - t2);
t4 = t1 * NewX;
NewX1 = (ILuint)(t4) * Image->Bpp;
NewX2 = (ILuint)(t4 + 1) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
Table[0][c] = t3 * FloatPtr[NewY1 + NewX1 + c] +
t2 * FloatPtr[NewY1 + NewX2 + c];
Table[1][c] = t3 * FloatPtr[NewY2 + NewX1 + c] +
t2 * FloatPtr[NewY2 + NewX2 + c];
}
// Linearly interpolate between the table values.
t1 = y / (ILdouble)(Height + 1); // Height+1 is the real height now.
t3 = (1.0 - t1);
Size = y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SFloatPtr[Size + c] =
(ILfloat)(t3 * Table[0][c] + t1 * Table[1][c]);
}
}
}
// Calculate the last row.
NewY1 = (ILuint)(Height / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX = Width / ScaleX;
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
ft = (t4 - (ILuint)(t4)) * IL_PI;
f = (1.0 - cos(ft)) * .5; // Cosine interpolation
NewX1 = (ILuint)(t1 * NewX) * Image->Bpp;
NewX2 = (ILuint)(t1 * NewX + 1) * Image->Bpp;
Size = Height * SclBps + x * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SFloatPtr[Size + c] = (ILfloat)((1.0 - f) * FloatPtr[NewY1 + NewX1 + c] +
f * FloatPtr[NewY1 + NewX2 + c]);
}
}
}
break;
}
return Scaled;
}
+313
View File
@@ -0,0 +1,313 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_scale.c
//
// Description: Scales an image.
//
//-----------------------------------------------------------------------------
// NOTE: Don't look at this file if you wish to preserve your sanity!
#include "ilu_internal.h"
#include "ilu_states.h"
ILimage *iluScale3DNear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth);
ILimage *iluScale3DLinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth);
ILimage *iluScale3DBilinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth);
static ILuint Size, NewX1, NewX2, NewY1, NewY2, NewZ1, NewZ2, x, y, z, c;
static ILdouble ScaleX, ScaleY, ScaleZ, x1, x2, t1, t2, t4, f, ft;
//ILdouble Table[2][2][4]; // Assumes we don't have larger than 32-bit images.
static ILuint ImgBps, SclBps, ImgPlane, SclPlane;
static ILushort *ShortPtr, *SShortPtr;
static ILuint *IntPtr, *SIntPtr;
ILimage *iluScale3D_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth)
{
if (Image == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
ScaleX = (ILfloat)Width / Image->Width;
ScaleY = (ILfloat)Height / Image->Height;
ScaleZ = (ILfloat)Depth / Image->Depth;
//if (iluFilter == ILU_NEAREST)
return iluScale3DNear_(Image, Scaled, Width, Height, Depth);
//else if (iluFilter == ILU_LINEAR)
//return iluScale3DLinear_(Image, Scaled, Width, Height, Depth);
// iluFilter == ILU_BILINEAR
//return iluScale3DBilinear_(Image, Scaled, Width, Height, Depth);
}
ILimage *iluScale3DNear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth)
{
ImgBps = Image->Bps / Image->Bpc;
SclBps = Scaled->Bps / Scaled->Bpc;
ImgPlane = Image->SizeOfPlane / Image->Bpc;
SclPlane = Scaled->SizeOfPlane / Scaled->Bpc;
switch (Image->Bpc)
{
case 1:
for (z = 0; z < Depth; z++) {
NewZ1 = z * SclPlane;
NewZ2 = (ILuint)(z / ScaleZ) * ImgPlane;
for (y = 0; y < Height; y++) {
NewY1 = y * SclBps;
NewY2 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
Scaled->Data[NewZ1 + NewY1 + NewX1 + c] =
Image->Data[NewZ2 + NewY2 + NewX2 + c];
}
}
}
}
break;
case 2:
ShortPtr = (ILushort*)Image->Data;
SShortPtr = (ILushort*)Scaled->Data;
for (z = 0; z < Depth; z++) {
NewZ1 = z * SclPlane;
NewZ2 = (ILuint)(z / ScaleZ) * ImgPlane;
for (y = 0; y < Height; y++) {
NewY1 = y * SclBps;
NewY2 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SShortPtr[NewZ1 + NewY1 + NewX1 + c] =
ShortPtr[NewZ2 + NewY2 + NewX2 + c];
}
}
}
}
break;
case 4:
IntPtr = (ILuint*)Image->Data;
SIntPtr = (ILuint*)Scaled->Data;
for (z = 0; z < Depth; z++) {
NewZ1 = z * SclPlane;
NewZ2 = (ILuint)(z / ScaleZ) * ImgPlane;
for (y = 0; y < Height; y++) {
NewY1 = y * SclBps;
NewY2 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
NewX1 = x * Scaled->Bpp;
NewX2 = (ILuint)(x / ScaleX) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
SIntPtr[NewZ1 + NewY1 + NewX1 + c] =
IntPtr[NewZ2 + NewY2 + NewX2 + c];
}
}
}
}
break;
}
return Scaled;
}
ILimage *iluScale3DLinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth)
{
ImgBps = Image->Bps / Image->Bpc;
SclBps = Scaled->Bps / Scaled->Bpc;
ImgPlane = Image->SizeOfPlane / Image->Bpc;
SclPlane = Scaled->SizeOfPlane / Scaled->Bpc;
switch (Image->Bpc)
{
case 1:
for (z = 0; z < Depth; z++) {
NewZ1 = (ILuint)(z / ScaleZ) * ImgPlane;
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
ft = t2 * IL_PI;
f = (1.0 - cos(ft)) * .5;
NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
Size = z * SclPlane + y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = Image->Data[NewZ1 + NewY1 + NewX1 + c];
x2 = Image->Data[NewZ1 + NewY1 + NewX2 + c];
Scaled->Data[Size + c] = (ILubyte)((1.0 - f) * x1 + f * x2);
}
}
}
}
break;
case 2:
ShortPtr = (ILushort*)Image->Data;
SShortPtr = (ILushort*)Scaled->Data;
for (z = 0; z < Depth; z++) {
NewZ1 = (ILuint)(z / ScaleZ) * ImgPlane;
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
ft = t2 * IL_PI;
f = (1.0 - cos(ft)) * .5;
NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
Size = z * SclPlane + y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = ShortPtr[NewZ1 + NewY1 + NewX1 + c];
x2 = ShortPtr[NewZ1 + NewY1 + NewX2 + c];
SShortPtr[Size + c] = (ILubyte)((1.0 - f) * x1 + f * x2);
}
}
}
}
break;
case 4:
IntPtr = (ILuint*)Image->Data;
SIntPtr = (ILuint*)Scaled->Data;
for (z = 0; z < Depth; z++) {
NewZ1 = (ILuint)(z / ScaleZ) * ImgPlane;
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * ImgBps;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
ft = t2 * IL_PI;
f = (1.0 - cos(ft)) * .5;
NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
Size = z * SclPlane + y * SclBps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = IntPtr[NewZ1 + NewY1 + NewX1 + c];
x2 = IntPtr[NewZ1 + NewY1 + NewX2 + c];
SIntPtr[Size + c] = (ILubyte)((1.0 - f) * x1 + f * x2);
}
}
}
}
break;
}
return Scaled;
}
/*ILimage *iluScale3DBilinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height, ILuint Depth);
{
Depth--; // Only use regular Depth once in the following loop.
Height--; // Only use regular Height once in the following loop.
for (z = 0; z < Depth; z++) {
NewZ1 = (ILuint)(z / ScaleZ) * Image->SizeOfPlane;
NewZ2 = (ILuint)((z+1) / ScaleZ) * Image->SizeOfPlane;
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * Image->Bps;
NewY2 = (ILuint)((y+1) / ScaleY) * Image->Bps;
for (x = 0; x < Width; x++) {
NewX = Width / ScaleX;
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
t3 = (1.0 - t2);
t4 = t1 * NewX;
NewX1 = (ILuint)(t4) * Image->Bpp;
NewX2 = (ILuint)(t4 + 1) * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
Table[0][0][c] = t3 * Image->Data[NewZ1 + NewY1 + NewX1 + c] +
t2 * Image->Data[NewZ1 + NewY1 + NewX2 + c];
Table[0][1][c] = t3 * Image->Data[NewZ1 + NewY2 + NewX1 + c] +
t2 * Image->Data[NewZ1 + NewY2 + NewX2 + c];
Table[1][0][c] = t3 * Image->Data[NewZ2 + NewY1 + NewX1 + c] +
t2 * Image->Data[NewZ2 + NewY1 + NewX2 + c];
Table[1][1][c] = t3 * Image->Data[NewZ2 + NewY2 + NewX1 + c] +
t2 * Image->Data[NewZ2 + NewY2 + NewX2 + c];
}
// Linearly interpolate between the table values.
t1 = y / (ILdouble)(Height + 1); // Height+1 is the real height now.
t2 = z / (ILdouble)(Depth + 1); // Depth+1 is the real depth now.
t3 = (1.0 - t1);
Size = z * Scaled->SizeOfPlane + y * Scaled->Bps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = t3 * Table[0][0][c] + t1 * Table[0][1][c];
x2 = t3 * Table[1][0][c] + t1 * Table[1][1][c];
Scaled->Data[Size + c] = (ILubyte)((1.0 - t2) * x1 + t2 * x2);
}
}
}
// Calculate the last row.
NewY1 = (ILuint)(Height / ScaleY) * Image->Bps;
for (x = 0; x < Width; x++) {
NewX = Width / ScaleX;
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
ft = (t4 - (ILuint)(t4)) * IL_PI;
f = (1.0 - cos(ft)) * .5; // Cosine interpolation
NewX1 = (ILuint)(t1 * NewX) * Image->Bpp;
NewX2 = (ILuint)(t1 * NewX + 1) * Image->Bpp;
Size = Height * Scaled->Bps + x * Image->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
Scaled->Data[Size + c] = (ILubyte)((1.0 - f) * Image->Data[NewY1 + NewX1 + c] +
f * Image->Data[NewY1 + NewX2 + c]);
}
}
}
NewZ1 = (ILuint)(Depth / ScaleZ) * Image->SizeOfPlane;
for (y = 0; y < Height; y++) {
NewY1 = (ILuint)(y / ScaleY) * Image->Bps;
for (x = 0; x < Width; x++) {
t1 = x / (ILdouble)Width;
t4 = t1 * Width;
t2 = t4 - (ILuint)(t4);
ft = t2 * IL_PI;
f = (1.0 - cos(ft)) * .5;
NewX1 = ((ILuint)(t4 / ScaleX)) * Image->Bpp;
NewX2 = ((ILuint)(t4 / ScaleX) + 1) * Image->Bpp;
Size = (Depth) * Scaled->SizeOfPlane + y * Scaled->Bps + x * Scaled->Bpp;
for (c = 0; c < Scaled->Bpp; c++) {
x1 = Image->Data[NewZ1 + NewY1 + NewX1 + c];
x2 = Image->Data[NewZ1 + NewY1 + NewX2 + c];
Scaled->Data[Size + c] = (ILubyte)((1.0 - f) * x1 + f * x2);
}
}
}
}
return Scaled;
}
*/
+466
View File
@@ -0,0 +1,466 @@
// http://www.cse.ucsc.edu/~pang/160/f98/Gems/GemsIII/
/*
* Filtered Image Rescaling
*
* by Dale Schumacher
*/
#if 0
#include "ilu_internal.h"
char _Copyright[] = "Public Domain 1991 by Dale Schumacher";
#define WHITE_PIXEL (255)
#define BLACK_PIXEL (0)
/*
* generic image access and i/o support routines
*/
ILubyte get_pixel(ILuint x, ILuint y)
{
Image *im = NULL;
int yy = -1;
Pixel *p = NULL;
if((x < 0) || (x >= image->xsize) || (y < 0) || (y >= image->ysize)) {
return(0);
}
if((im != image) || (yy != y)) {
im = image;
yy = y;
p = image->data + (y * image->span);
}
return(p[x]);
}
void
get_row(row, image, y)
Pixel *row;
Image *image;
int y;
{
if((y < 0) || (y >= image->ysize)) {
return;
}
memcpy(row,
image->data + (y * image->span),
(sizeof(Pixel) * image->xsize));
}
void
get_column(column, image, x)
Pixel *column;
Image *image;
int x;
{
int i, d;
Pixel *p;
if((x < 0) || (x >= image->xsize)) {
return;
}
d = image->span;
for(i = image->ysize, p = image->data + x; i-- > 0; p += d) {
*column++ = *p;
}
}
Pixel
put_pixel(image, x, y, data)
Image *image;
int x, y;
Pixel data;
{
Image *im = NULL;
ILint yy = -1;
Pixel *p = NULL;
if((x < 0) || (x >= image->xsize) || (y < 0) || (y >= image->ysize)) {
return(0);
}
if((im != image) || (yy != y)) {
im = image;
yy = y;
p = image->data + (y * image->span);
}
return(p[x] = data);
}
/*
* filter function definitions
*/
#define filter_support (1.0)
double filter( double t) {
/* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
if(t < 0.0) t = -t;
if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0);
return(0.0);
}
#define box_support (0.5)
double box_filter( double t) {
if((t > -0.5) && (t <= 0.5)) return(1.0);
return(0.0);
}
#define triangle_support (1.0)
double triangle_filter( double t ) {
if(t < 0.0) t = -t;
if(t < 1.0) return(1.0 - t);
return(0.0);
}
#define bell_support (1.5)
double bell_filter( double t) { /* box (*) box (*) box */
if(t < 0) t = -t;
if(t < .5) return(.75 - (t * t));
if(t < 1.5) {
t = (t - 1.5);
return(.5 * (t * t));
}
return(0.0);
}
#define B_spline_support (2.0)
double
B_spline_filter(t) /* box (*) box (*) box (*) box */
double t;
{
double tt;
if(t < 0) t = -t;
if(t < 1) {
tt = t * t;
return((.5 * tt * t) - tt + (2.0 / 3.0));
} else if(t < 2) {
t = 2 - t;
return((1.0 / 6.0) * (t * t * t));
}
return(0.0);
}
double
sinc(x)
double x;
{
x *= IL_PI;
if(x != 0) return(sin(x) / x);
return(1.0);
}
#define Lanczos3_support (3.0)
double
Lanczos3_filter(t)
double t;
{
if(t < 0) t = -t;
if(t < 3.0) return(sinc(t) * sinc(t/3.0));
return(0.0);
}
#define Mitchell_support (2.0)
#define B (1.0 / 3.0)
#define C (1.0 / 3.0)
double
Mitchell_filter(t)
double t;
{
double tt;
tt = t * t;
if(t < 0) t = -t;
if(t < 1.0) {
t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt))
+ ((-18.0 + 12.0 * B + 6.0 * C) * tt)
+ (6.0 - 2 * B));
return(t / 6.0);
} else if(t < 2.0) {
t = (((-1.0 * B - 6.0 * C) * (t * tt))
+ ((6.0 * B + 30.0 * C) * tt)
+ ((-12.0 * B - 48.0 * C) * t)
+ (8.0 * B + 24 * C));
return(t / 6.0);
}
return(0.0);
}
/*
* image rescaling routine
*/
typedef struct {
int pixel;
double weight;
} CONTRIB;
typedef struct {
int n; /* number of contributors */
CONTRIB *p; /* pointer to list of contributions */
} CLIST;
CLIST *contrib; /* array of contribution lists */
void
zoom(dst, src, filterf, fwidth)
Image *dst; /* destination image structure */
Image *src; /* source image structure */
double (*filterf)(); /* filter function */
double fwidth; /* filter width (support) */
{
Image *tmp; /* intermediate image */
double xscale, yscale; /* zoom scale factors */
int i, j, k; /* loop variables */
int n; /* pixel number */
double center, left, right; /* filter calculation variables */
double width, fscale, weight; /* filter calculation variables */
Pixel *raster; /* a row or column of pixels */
/* create intermediate image to hold horizontal zoom */
tmp = new_image(dst->xsize, src->ysize);
xscale = (double) dst->xsize / (double) src->xsize;
yscale = (double) dst->ysize / (double) src->ysize;
/* pre-calculate filter contributions for a row */
contrib = (CLIST*)icalloc(dst->xsize, sizeof(CLIST));
if(xscale < 1.0) {
width = fwidth / xscale;
fscale = 1.0 / xscale;
for(i = 0; i < dst->xsize; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB*)icalloc((int) (width * 2 + 1),
sizeof(CONTRIB));
center = (double) i / xscale;
left = ceil(center - width);
right = floor(center + width);
for(j = left; j <= right; ++j) {
weight = center - (double) j;
weight = (*filterf)(weight / fscale) / fscale;
if(j < 0) {
n = -j;
} else if(j >= src->xsize) {
n = (src->xsize - j) + src->xsize - 1;
} else {
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n;
contrib[i].p[k].weight = weight;
}
}
} else {
for(i = 0; i < dst->xsize; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB*)icalloc((int) (fwidth * 2 + 1), sizeof(CONTRIB));
center = (double) i / xscale;
left = ceil(center - fwidth);
right = floor(center + fwidth);
for(j = left; j <= right; ++j) {
weight = center - (double) j;
weight = (*filterf)(weight);
if(j < 0) {
n = -j;
} else if(j >= src->xsize) {
n = (src->xsize - j) + src->xsize - 1;
} else {
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n;
contrib[i].p[k].weight = weight;
}
}
}
/* apply filter to zoom horizontally from src to tmp */
raster = (Pixel*)icalloc(src->xsize, sizeof(Pixel));
for(k = 0; k < tmp->ysize; ++k) {
get_row(raster, src, k);
for(i = 0; i < tmp->xsize; ++i) {
weight = 0.0;
for(j = 0; j < contrib[i].n; ++j) {
weight += raster[contrib[i].p[j].pixel]
* contrib[i].p[j].weight;
}
put_pixel(tmp, i, k,
(Pixel)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL));
}
}
ifree(raster);
/* free the memory allocated for horizontal filter weights */
for(i = 0; i < tmp->xsize; ++i) {
ifree(contrib[i].p);
}
ifree(contrib);
/* pre-calculate filter contributions for a column */
contrib = (CLIST*)icalloc(dst->ysize, sizeof(CLIST));
if(yscale < 1.0) {
width = fwidth / yscale;
fscale = 1.0 / yscale;
for(i = 0; i < dst->ysize; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB*)icalloc((int) (width * 2 + 1), sizeof(CONTRIB));
center = (double) i / yscale;
left = ceil(center - width);
right = floor(center + width);
for(j = left; j <= right; ++j) {
weight = center - (double) j;
weight = (*filterf)(weight / fscale) / fscale;
if(j < 0) {
n = -j;
} else if(j >= tmp->ysize) {
n = (tmp->ysize - j) + tmp->ysize - 1;
} else {
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n;
contrib[i].p[k].weight = weight;
}
}
} else {
for(i = 0; i < dst->ysize; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB*)icalloc((int) (fwidth * 2 + 1),
sizeof(CONTRIB));
center = (double) i / yscale;
left = ceil(center - fwidth);
right = floor(center + fwidth);
for(j = left; j <= right; ++j) {
weight = center - (double) j;
weight = (*filterf)(weight);
if(j < 0) {
n = -j;
} else if(j >= tmp->ysize) {
n = (tmp->ysize - j) + tmp->ysize - 1;
} else {
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n;
contrib[i].p[k].weight = weight;
}
}
}
/* apply filter to zoom vertically from tmp to dst */
raster = (Pixel*)icalloc(tmp->ysize, sizeof(Pixel));
for(k = 0; k < dst->xsize; ++k) {
get_column(raster, tmp, k);
for(i = 0; i < dst->ysize; ++i) {
weight = 0.0;
for(j = 0; j < contrib[i].n; ++j) {
weight += raster[contrib[i].p[j].pixel]
* contrib[i].p[j].weight;
}
put_pixel(dst, k, i,
(Pixel)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL));
}
}
ifree(raster);
/* free the memory allocated for vertical filter weights */
for(i = 0; i < dst->ysize; ++i) {
ifree(contrib[i].p);
}
ifree(contrib);
free_image(tmp);
}
/*
* command line interface
*/
void
usage()
{
fprintf(stderr, "usage: %s [-options] input.bm output.bm\n", _Program);
fprintf(stderr, "\
options:\n\
-x xsize output x size\n\
-y ysize output y size\n\
-f filter filter type\n\
{b=box, t=triangle, q=bell, B=B-spline, h=hermite, l=Lanczos3, m=Mitchell}\n\
");
exit(1);
}
main(argc, argv)
int argc;
char *argv[];
{
register int c;
int optind;
char *optarg;
int xsize = 0, ysize = 0;
double (*f)() = filter;
double s = filter_support;
char *dstfile, *srcfile;
Image *dst, *src;
FILE *fp;
while((c = getopt(argc, argv, "x:y:f:V")) != EOF) {
switch(c) {
case 'x': xsize = atoi(optarg); break;
case 'y': ysize = atoi(optarg); break;
case 'f':
switch(*optarg) {
case 'b': f=box_filter; s=box_support; break;
case 't': f=triangle_filter; s=triangle_support; break;
case 'q': f=bell_filter; s=bell_support; break;
case 'B': f=B_spline_filter; s=B_spline_support; break;
case 'h': f=filter; s=filter_support; break;
case 'l': f=Lanczos3_filter; s=Lanczos3_support; break;
case 'm': f=Mitchell_filter; s=Mitchell_support; break;
default: usage();
}
break;
case 'V': banner(); exit(EXIT_SUCCESS);
case '?': usage();
default: usage();
}
}
if((argc - optind) != 2) usage();
srcfile = argv[optind];
dstfile = argv[optind + 1];
if(((fp = fopen(srcfile, "r")) == NULL)
|| ((src = load_image(fp)) == NULL)) {
fprintf(stderr, "%s: can't load source image '%s'\n",
_Program, srcfile);
exit(EXIT_FAILURE);
}
fclose(fp);
if(xsize <= 0) xsize = src->xsize;
if(ysize <= 0) ysize = src->ysize;
dst = new_image(xsize, ysize);
zoom(dst, src, f, s);
if(((fp = fopen(dstfile, "w")) == NULL)
|| (save_image(fp, dst) != 0)) {
fprintf(stderr, "%s: can't save destination image '%s'\n",
_Program, dstfile);
exit(EXIT_FAILURE);
}
fclose(fp);
exit(EXIT_SUCCESS);
}
#endif
+115
View File
@@ -0,0 +1,115 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-ILU/src/ilu_states.c
//
// Description: The state machine
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
#include "ilu_states.h"
ILconst_string _iluVendor = IL_TEXT("Abysmal Software");
ILconst_string _iluVersion = IL_TEXT("Developer's Image Library Utilities (ILU) 1.7.8");// IL_TEXT(__DATE__));
ILstring ILAPIENTRY iluGetString(ILenum StringName)
{
switch (StringName)
{
case ILU_VENDOR:
return (ILstring)_iluVendor;
//changed 2003-09-04
case ILU_VERSION_NUM:
return (ILstring)_iluVersion;
default:
ilSetError(ILU_INVALID_PARAM);
break;
}
return NULL;
}
void ILAPIENTRY iluGetIntegerv(ILenum Mode, ILint *Param)
{
switch (Mode)
{
case ILU_VERSION_NUM:
*Param = ILU_VERSION;
break;
case ILU_FILTER:
*Param = iluFilter;
break;
default:
ilSetError(ILU_INVALID_ENUM);
}
return;
}
ILint ILAPIENTRY iluGetInteger(ILenum Mode)
{
ILint Temp;
Temp = 0;
iluGetIntegerv(Mode, &Temp);
return Temp;
}
ILenum iluFilter = ILU_NEAREST;
ILenum iluPlacement = ILU_CENTER;
void ILAPIENTRY iluImageParameter(ILenum PName, ILenum Param)
{
switch (PName)
{
case ILU_FILTER:
switch (Param)
{
case ILU_NEAREST:
case ILU_LINEAR:
case ILU_BILINEAR:
case ILU_SCALE_BOX:
case ILU_SCALE_TRIANGLE:
case ILU_SCALE_BELL:
case ILU_SCALE_BSPLINE:
case ILU_SCALE_LANCZOS3:
case ILU_SCALE_MITCHELL:
iluFilter = Param;
break;
default:
ilSetError(ILU_INVALID_ENUM);
return;
}
break;
case ILU_PLACEMENT:
switch (Param)
{
case ILU_LOWER_LEFT:
case ILU_LOWER_RIGHT:
case ILU_UPPER_LEFT:
case ILU_UPPER_RIGHT:
case ILU_CENTER:
iluPlacement = Param;
break;
default:
ilSetError(ILU_INVALID_ENUM);
return;
}
break;
default:
ilSetError(ILU_INVALID_ENUM);
return;
}
return;
}
@@ -0,0 +1,63 @@
//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_utilities.c
//
// Description: Utility functions
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
void ILAPIENTRY iluDeleteImage(ILuint Id)
{
ilDeleteImages(1, &Id);
return;
}
ILuint ILAPIENTRY iluGenImage()
{
ILuint Id;
ilGenImages(1, &Id);
ilBindImage(Id);
return Id;
}
//! Retrieves information about the current bound image.
void ILAPIENTRY iluGetImageInfo(ILinfo *Info)
{
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL || Info == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return;
}
Info->Id = ilGetCurName();
Info->Data = ilGetData();
Info->Width = iluCurImage->Width;
Info->Height = iluCurImage->Height;
Info->Depth = iluCurImage->Depth;
Info->Bpp = iluCurImage->Bpp;
Info->SizeOfData = iluCurImage->SizeOfData;
Info->Format = iluCurImage->Format;
Info->Type = iluCurImage->Type;
Info->Origin = iluCurImage->Origin;
Info->Palette = iluCurImage->Pal.Palette;
Info->PalType = iluCurImage->Pal.PalType;
Info->PalSize = iluCurImage->Pal.PalSize;
iGetIntegervImage(iluCurImage, IL_NUM_IMAGES,
(ILint*)&Info->NumNext);
iGetIntegervImage(iluCurImage, IL_NUM_MIPMAPS,
(ILint*)&Info->NumMips);
iGetIntegervImage(iluCurImage, IL_NUM_LAYERS,
(ILint*)&Info->NumLayers);
return;
}