mirror of
https://github.com/love2d/love-android.git
synced 2026-08-17 19:24:07 +02:00
added dependencies and build files (loosely inspired by Sebastian Dorda's love-native-android)
This commit is contained in:
@@ -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)
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}*/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user