mirror of https://github.com/nothings/stb-imv
cleanup free image, error message, 'f' to 'b'
This commit is contained in:
parent
2255e9fd57
commit
b9250aa2a5
222
imv.c
222
imv.c
|
@ -20,6 +20,7 @@
|
||||||
#pragma comment(linker, "/FILEALIGN:0x200")
|
#pragma comment(linker, "/FILEALIGN:0x200")
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0500
|
#define _WIN32_WINNT 0x0500
|
||||||
|
//#define WINVER 0x0500 // produces an annoying warning message, so we do it the hard way
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -419,6 +420,7 @@ start:
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8 *imv_decode_from_memory(uint8 *mem, int len, int *x, int *y, int *n, int n_req);
|
static uint8 *imv_decode_from_memory(uint8 *mem, int len, int *x, int *y, int *n, int n_req);
|
||||||
|
static char *imv_failure_reason(void);
|
||||||
|
|
||||||
void *decode_task(void *p)
|
void *decode_task(void *p)
|
||||||
{
|
{
|
||||||
|
@ -448,7 +450,7 @@ void *decode_task(void *p)
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
// error reading file, record the reason for it
|
// error reading file, record the reason for it
|
||||||
f->error = strdup(stbi_failure_reason());
|
f->error = strdup(imv_failure_reason());
|
||||||
barrier();
|
barrier();
|
||||||
f->status = LOAD_error_reading;
|
f->status = LOAD_error_reading;
|
||||||
// wake up the main thread in case this is the most recent image
|
// wake up the main thread in case this is the most recent image
|
||||||
|
@ -548,7 +550,7 @@ int downsample_cubic = 0;
|
||||||
int upsample_cubic = TRUE;
|
int upsample_cubic = TRUE;
|
||||||
|
|
||||||
// declare with extra bytes so we can print the version number into it
|
// declare with extra bytes so we can print the version number into it
|
||||||
char helptext_center[104] =
|
char helptext_center[140] =
|
||||||
"imv(stb)\n"
|
"imv(stb)\n"
|
||||||
"Copyright 2007 Sean Barrett\n"
|
"Copyright 2007 Sean Barrett\n"
|
||||||
"http://code.google.com/p/stb-imv\n"
|
"http://code.google.com/p/stb-imv\n"
|
||||||
|
@ -556,7 +558,7 @@ char helptext_center[104] =
|
||||||
;
|
;
|
||||||
|
|
||||||
char helptext_left[] =
|
char helptext_left[] =
|
||||||
"\n\n\n\n\n"
|
"\n\n\n\n\n\n"
|
||||||
" ESC: exit\n"
|
" ESC: exit\n"
|
||||||
" ALT-ENTER: toggle size\n"
|
" ALT-ENTER: toggle size\n"
|
||||||
" CTRL-PLUS: zoom in\n"
|
" CTRL-PLUS: zoom in\n"
|
||||||
|
@ -565,15 +567,15 @@ char helptext_left[] =
|
||||||
"LEFT, BACKSPACE: previous image\n"
|
"LEFT, BACKSPACE: previous image\n"
|
||||||
" (CTRL-) O: open image\n"
|
" (CTRL-) O: open image\n"
|
||||||
" P: change preferences\n"
|
" P: change preferences\n"
|
||||||
" F: toggle frame\n"
|
" B: toggle border\n"
|
||||||
"SHIFT-F: toggle frame but keep stripe\n"
|
"SHIFT-B: toggle border but keep stripe\n"
|
||||||
" CTRL-F: toggle white stripe in frame\n"
|
" CTRL-B: toggle white stripe in border\n"
|
||||||
" L: toggle filename label\n"
|
" L: toggle filename label\n"
|
||||||
"F1, H, ?: help"
|
"F1, H, ?: help"
|
||||||
;
|
;
|
||||||
|
|
||||||
char helptext_right[] =
|
char helptext_right[] =
|
||||||
"\n\n\n\n\n\n"
|
"\n\n\n\n\n\n\n"
|
||||||
"right-click to exit\n"
|
"right-click to exit\n"
|
||||||
"left drag center to move\n"
|
"left drag center to move\n"
|
||||||
"left drag edges to resize\n"
|
"left drag edges to resize\n"
|
||||||
|
@ -1496,15 +1498,16 @@ static int rx,ry; // sides that are being resized
|
||||||
static void cursor_regions(int *x0, int *y0, int *x1, int *y1)
|
static void cursor_regions(int *x0, int *y0, int *x1, int *y1)
|
||||||
{
|
{
|
||||||
RECT rect;
|
RECT rect;
|
||||||
int w,h,w2;
|
int w,h,z2,z;
|
||||||
GetClientRect(win, &rect);
|
GetClientRect(win, &rect);
|
||||||
// client dimensions
|
// client dimensions
|
||||||
|
assert(rect.left == 0 && rect.top == 0);
|
||||||
w = rect.right;
|
w = rect.right;
|
||||||
h = rect.bottom;
|
h = rect.bottom;
|
||||||
|
|
||||||
// size of resize regions is identical in both axes, so
|
// size of resize regions is identical in both axes, so
|
||||||
// use smaller window size
|
// use smaller window size
|
||||||
w = stb_min(w,h);
|
z = stb_min(w,h);
|
||||||
|
|
||||||
// compute size of handles
|
// compute size of handles
|
||||||
// this is a pretty ad-hoc logic that is designed to:
|
// this is a pretty ad-hoc logic that is designed to:
|
||||||
|
@ -1512,16 +1515,16 @@ static void cursor_regions(int *x0, int *y0, int *x1, int *y1)
|
||||||
// - but not too big
|
// - but not too big
|
||||||
// - make them smaller with smaller windows, so there's still an ample 'move' region
|
// - make them smaller with smaller windows, so there's still an ample 'move' region
|
||||||
// - but not too small
|
// - but not too small
|
||||||
if (w < 16) w2 = w >> 1;
|
if (z < 16) z2 = z >> 1;
|
||||||
else if (w < 200) w2 = w >> 2;
|
else if (z < 200) z2 = z >> 2;
|
||||||
else if (w < 800) w2 = w >> 3;
|
else if (z < 800) z2 = z >> 3;
|
||||||
else if (w < 1600) w2 = w >> 4;
|
else if (z < 1600) z2 = z >> 4;
|
||||||
else w2 = 100;
|
else z2 = 100;
|
||||||
|
|
||||||
*x0 = w2;
|
*x0 = z2;
|
||||||
*x1 = w - w2;
|
*x1 = w - z2;
|
||||||
*y0 = w2;
|
*y0 = z2;
|
||||||
*y1 = h - w2;
|
*y1 = h - z2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static cursor cache of standard windows cursor for resizing
|
// static cursor cache of standard windows cursor for resizing
|
||||||
|
@ -1743,6 +1746,7 @@ BOOL CALLBACK PrefDlgProc(HWND hdlg, UINT imsg, WPARAM wparam, LPARAM lparam)
|
||||||
for (k=0; k < 3; ++k)
|
for (k=0; k < 3; ++k)
|
||||||
pref_image->pixels[pref_image->stride*j + BPP*i + k] = data[j*x+i];
|
pref_image->pixels[pref_image->stride*j + BPP*i + k] = data[j*x+i];
|
||||||
}
|
}
|
||||||
|
if (data) free(data);
|
||||||
|
|
||||||
// copy preferences into dialog
|
// copy preferences into dialog
|
||||||
SendMessage(GetDlgItem(hdlg, DIALOG_upsample), BM_SETCHECK, upsample_cubic, 0);
|
SendMessage(GetDlgItem(hdlg, DIALOG_upsample), BM_SETCHECK, upsample_cubic, 0);
|
||||||
|
@ -1755,18 +1759,21 @@ BOOL CALLBACK PrefDlgProc(HWND hdlg, UINT imsg, WPARAM wparam, LPARAM lparam)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case WM_PAINT: {
|
case WM_PAINT: {
|
||||||
// draw the preferences image
|
if (pref_image) {
|
||||||
RECT z;
|
// draw the preferences image
|
||||||
int x,y;
|
RECT z;
|
||||||
HWND pic = GetDlgItem(hdlg, DIALOG_image);
|
int x,y;
|
||||||
GetWindowRect(pic,&z);
|
HWND pic = GetDlgItem(hdlg, DIALOG_image);
|
||||||
// not clear why these next two lines work/are required, but it's what petzold does
|
GetWindowRect(pic,&z);
|
||||||
InvalidateRect(pic,NULL,TRUE);
|
// not clear why these next two lines work/are required, but it's what petzold does;
|
||||||
UpdateWindow(pic);
|
// doesn't UpdateWindow() just force a WM_PAINT? why isn't this an infinite loop?
|
||||||
// center it
|
InvalidateRect(pic,NULL,TRUE);
|
||||||
x = (z.right - z.left - pref_image->x) >> 1;
|
UpdateWindow(pic);
|
||||||
y = (z.bottom - z.top - pref_image->y) >> 1;
|
// center it
|
||||||
platformDrawBitmap(GetDC(pic), x,y,pref_image->pixels,pref_image->x,pref_image->y,pref_image->stride,0);
|
x = (z.right - z.left - pref_image->x) >> 1;
|
||||||
|
y = (z.bottom - z.top - pref_image->y) >> 1;
|
||||||
|
platformDrawBitmap(GetDC(pic), x,y,pref_image->pixels,pref_image->x,pref_image->y,pref_image->stride,0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_COMMAND: {
|
case WM_COMMAND: {
|
||||||
|
@ -1789,6 +1796,7 @@ BOOL CALLBACK PrefDlgProc(HWND hdlg, UINT imsg, WPARAM wparam, LPARAM lparam)
|
||||||
case IDOK: {
|
case IDOK: {
|
||||||
// user clicked ok... copy out current values to check for changes
|
// user clicked ok... copy out current values to check for changes
|
||||||
unsigned char cur[6];
|
unsigned char cur[6];
|
||||||
|
int old_cubic = upsample_cubic;
|
||||||
memcpy(cur, alpha_background, 6);
|
memcpy(cur, alpha_background, 6);
|
||||||
|
|
||||||
// load the settings back out of the dialog box
|
// load the settings back out of the dialog box
|
||||||
|
@ -1818,7 +1826,8 @@ BOOL CALLBACK PrefDlgProc(HWND hdlg, UINT imsg, WPARAM wparam, LPARAM lparam)
|
||||||
stb_mutex_end(cache_mutex);
|
stb_mutex_end(cache_mutex);
|
||||||
// force a reload of the current image
|
// force a reload of the current image
|
||||||
advance(0);
|
advance(0);
|
||||||
}
|
} else if (old_cubic != upsample_cubic)
|
||||||
|
advance(0);
|
||||||
|
|
||||||
// save the data out to the registry
|
// save the data out to the registry
|
||||||
reg_save();
|
reg_save();
|
||||||
|
@ -2048,21 +2057,22 @@ int WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
InvalidateRect(win, NULL, FALSE);
|
InvalidateRect(win, NULL, FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'F' | MY_CTRL:
|
case 'B' | MY_CTRL:
|
||||||
extra_border = !extra_border;
|
extra_border = !extra_border;
|
||||||
if (cur) frame(cur);
|
if (cur) frame(cur);
|
||||||
InvalidateRect(win, NULL, FALSE);
|
InvalidateRect(win, NULL, FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'F' | MY_SHIFT:
|
case 'B' | MY_SHIFT:
|
||||||
toggle_frame();
|
toggle_frame();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'F':
|
case 'B':
|
||||||
toggle_frame();
|
toggle_frame();
|
||||||
extra_border = show_frame;
|
extra_border = show_frame;
|
||||||
if (cur) frame(cur);
|
if (cur) frame(cur);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef PERFTEST
|
#ifdef PERFTEST
|
||||||
case 'D' | MY_CTRL:
|
case 'D' | MY_CTRL:
|
||||||
performance_test();
|
performance_test();
|
||||||
|
@ -2141,7 +2151,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
|
|
||||||
// determine the number of threads to use in the resizer
|
// determine the number of threads to use in the resizer
|
||||||
resize_threads = stb_min(stb_processor_count(), 16);
|
resize_threads = stb_min(stb_processor_count(), 16);
|
||||||
resize_threads = 8;
|
|
||||||
|
|
||||||
// compute the amount of physical memory to set a guess for the cache size
|
// compute the amount of physical memory to set a guess for the cache size
|
||||||
GlobalMemoryStatus(&mem);
|
GlobalMemoryStatus(&mem);
|
||||||
|
@ -2161,7 +2170,7 @@ resize_threads = 8;
|
||||||
// that way only_stbi can be used to suppress errors
|
// that way only_stbi can be used to suppress errors
|
||||||
#ifdef USE_FREEIMAGE
|
#ifdef USE_FREEIMAGE
|
||||||
if (LoadFreeImage()) {
|
if (LoadFreeImage()) {
|
||||||
strcat(helptext_center, "\nUsing FreeImage.dll");
|
strcat(helptext_center, "\nUsing FreeImage.dll: http://freeimage.sourceforge.net");
|
||||||
open_filter = "Image Files\0*.jpg;*.jpeg;*.png;*.bmp;*.dds;*.gif;*.ico;*.jng;*.lbm;*.pcx;*.ppm;*.psd;*.tga;*.tiff\0";
|
open_filter = "Image Files\0*.jpg;*.jpeg;*.png;*.bmp;*.dds;*.gif;*.ico;*.jng;*.lbm;*.pcx;*.ppm;*.psd;*.tga;*.tiff\0";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2175,7 +2184,7 @@ resize_threads = 8;
|
||||||
wndclass.hInstance = hInstance;
|
wndclass.hInstance = hInstance;
|
||||||
wndclass.hIcon = LoadIcon(hInstance, szAppName);
|
wndclass.hIcon = LoadIcon(hInstance, szAppName);
|
||||||
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
|
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
|
||||||
wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
|
wndclass.hbrBackground = NULL;
|
||||||
wndclass.lpszMenuName = szAppName;
|
wndclass.lpszMenuName = szAppName;
|
||||||
wndclass.lpszClassName = szAppName;
|
wndclass.lpszClassName = szAppName;
|
||||||
wndclass.hIconSm = LoadIcon(hInstance, szAppName);
|
wndclass.hIconSm = LoadIcon(hInstance, szAppName);
|
||||||
|
@ -2224,7 +2233,7 @@ resize_threads = 8;
|
||||||
else {
|
else {
|
||||||
image_data = imv_decode_from_memory(data, len, &image_x, &image_y, &image_n, BPP);
|
image_data = imv_decode_from_memory(data, len, &image_x, &image_y, &image_n, BPP);
|
||||||
if (image_data == NULL)
|
if (image_data == NULL)
|
||||||
why = stbi_failure_reason();
|
why = imv_failure_reason();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (why) {
|
if (why) {
|
||||||
|
@ -2356,7 +2365,9 @@ resize_threads = 8;
|
||||||
// free the current image we're about to write over
|
// free the current image we're about to write over
|
||||||
imfree(cur);
|
imfree(cur);
|
||||||
cur = pending_resize.image;
|
cur = pending_resize.image;
|
||||||
|
// pending_resize.filename was strdup()ed, so just take ownership of it
|
||||||
cur_filename = pending_resize.filename;
|
cur_filename = pending_resize.filename;
|
||||||
|
pending_resize.filename = NULL;
|
||||||
|
|
||||||
// clear error messages
|
// clear error messages
|
||||||
display_error[0] = 0;
|
display_error[0] = 0;
|
||||||
|
@ -2372,7 +2383,6 @@ resize_threads = 8;
|
||||||
SetWindowPos(hWnd,NULL,pending_resize.size.x, pending_resize.size.y, pending_resize.size.w, pending_resize.size.h, SWP_NOZORDER);
|
SetWindowPos(hWnd,NULL,pending_resize.size.x, pending_resize.size.y, pending_resize.size.w, pending_resize.size.h, SWP_NOZORDER);
|
||||||
|
|
||||||
// clear the resize request info
|
// clear the resize request info
|
||||||
pending_resize.filename = NULL;
|
|
||||||
barrier();
|
barrier();
|
||||||
pending_resize.size.w = 0;
|
pending_resize.size.w = 0;
|
||||||
|
|
||||||
|
@ -3002,7 +3012,13 @@ void image_resize(Image *dest, Image *src)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char imv_failure_buffer[1024];
|
||||||
|
char *imv_failure_string;
|
||||||
|
|
||||||
|
static char *imv_failure_reason(void)
|
||||||
|
{
|
||||||
|
return imv_failure_string;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_FREEIMAGE
|
#ifdef USE_FREEIMAGE
|
||||||
|
|
||||||
|
@ -3060,7 +3076,8 @@ static freeimage_istransparent *FreeImage_IsTransparent;
|
||||||
static void
|
static void
|
||||||
FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message)
|
FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message)
|
||||||
{
|
{
|
||||||
assert(!"FreeImage failure");
|
strcpy(imv_failure_buffer, message);
|
||||||
|
imv_failure_string = imv_failure_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HINSTANCE FreeImageDLL;
|
static HINSTANCE FreeImageDLL;
|
||||||
|
@ -3075,88 +3092,81 @@ FARPROC fifunc(char *str)
|
||||||
|
|
||||||
static int LoadFreeImage(void)
|
static int LoadFreeImage(void)
|
||||||
{
|
{
|
||||||
static int InitializationAttempted;
|
static int InitializationAttempted;
|
||||||
if(!InitializationAttempted)
|
if (InitializationAttempted) return FreeImagePresent;
|
||||||
{
|
|
||||||
FreeImageDLL = LoadLibrary("FreeImage.dll");
|
|
||||||
if(FreeImageDLL)
|
|
||||||
{
|
|
||||||
FreeImagePresent = TRUE;
|
|
||||||
FreeImage_ConvertToRawBits = (freeimage_converttorawbits *)fifunc("_FreeImage_ConvertToRawBits@32");
|
|
||||||
FreeImage_GetBits = (freeimage_getbits *)fifunc("_FreeImage_GetBits@4");
|
|
||||||
FreeImage_GetFIFFromFilename = (freeimage_getfiffromfilename *)fifunc("_FreeImage_GetFIFFromFilename@4");
|
|
||||||
FreeImage_GetFileTypeFromMemory = (freeimage_getfiletypefrommemory *)fifunc("_FreeImage_GetFileTypeFromMemory@8");
|
|
||||||
FreeImage_GetHeight = (freeimage_getheight *)fifunc("_FreeImage_GetHeight@4");
|
|
||||||
FreeImage_GetWidth = (freeimage_getwidth *)fifunc("_FreeImage_GetWidth@4");
|
|
||||||
FreeImage_LoadFromMemory = (freeimage_loadfrommemory *)fifunc("_FreeImage_LoadFromMemory@12");
|
|
||||||
FreeImage_SetOutputMessage = (freeimage_setoutputmessage *)fifunc("_FreeImage_SetOutputMessage@4");
|
|
||||||
FreeImage_Unload = (freeimage_unload *)fifunc("_FreeImage_Unload@4");
|
|
||||||
FreeImage_OpenMemory = (freeimage_openmemory *)fifunc("_FreeImage_OpenMemory@8");
|
|
||||||
FreeImage_CloseMemory = (freeimage_closememory *)fifunc("_FreeImage_CloseMemory@4");
|
|
||||||
FreeImage_SeekMemory = (freeimage_seekmemory *)fifunc("_FreeImage_SeekMemory@12");
|
|
||||||
FreeImage_IsTransparent = (freeimage_istransparent *)fifunc("_FreeImage_IsTransparent@4");
|
|
||||||
|
|
||||||
if (!FreeImagePresent) {
|
InitializationAttempted = TRUE;
|
||||||
if (!only_stbi)
|
FreeImagePresent = FALSE;
|
||||||
error("Invalid FreeImage.dll; disabling FreeImage support.");
|
FreeImageDLL = LoadLibrary("FreeImage.dll");
|
||||||
} else
|
if (!FreeImageDLL) return FreeImagePresent;
|
||||||
FreeImage_SetOutputMessage(FreeImageErrorHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializationAttempted = TRUE;
|
FreeImagePresent = TRUE;
|
||||||
}
|
FreeImage_ConvertToRawBits = (freeimage_converttorawbits *)fifunc("_FreeImage_ConvertToRawBits@32");
|
||||||
|
FreeImage_GetBits = (freeimage_getbits *)fifunc("_FreeImage_GetBits@4");
|
||||||
|
FreeImage_GetFIFFromFilename = (freeimage_getfiffromfilename *)fifunc("_FreeImage_GetFIFFromFilename@4");
|
||||||
|
FreeImage_GetFileTypeFromMemory = (freeimage_getfiletypefrommemory *)fifunc("_FreeImage_GetFileTypeFromMemory@8");
|
||||||
|
FreeImage_GetHeight = (freeimage_getheight *)fifunc("_FreeImage_GetHeight@4");
|
||||||
|
FreeImage_GetWidth = (freeimage_getwidth *)fifunc("_FreeImage_GetWidth@4");
|
||||||
|
FreeImage_LoadFromMemory = (freeimage_loadfrommemory *)fifunc("_FreeImage_LoadFromMemory@12");
|
||||||
|
FreeImage_SetOutputMessage = (freeimage_setoutputmessage *)fifunc("_FreeImage_SetOutputMessage@4");
|
||||||
|
FreeImage_Unload = (freeimage_unload *)fifunc("_FreeImage_Unload@4");
|
||||||
|
FreeImage_OpenMemory = (freeimage_openmemory *)fifunc("_FreeImage_OpenMemory@8");
|
||||||
|
FreeImage_CloseMemory = (freeimage_closememory *)fifunc("_FreeImage_CloseMemory@4");
|
||||||
|
FreeImage_SeekMemory = (freeimage_seekmemory *)fifunc("_FreeImage_SeekMemory@12");
|
||||||
|
FreeImage_IsTransparent = (freeimage_istransparent *)fifunc("_FreeImage_IsTransparent@4");
|
||||||
|
|
||||||
return(FreeImagePresent);
|
if (!FreeImagePresent) {
|
||||||
|
if (!only_stbi)
|
||||||
|
error("Invalid FreeImage.dll; disabling FreeImage support.");
|
||||||
|
} else
|
||||||
|
FreeImage_SetOutputMessage(FreeImageErrorHandler);
|
||||||
|
|
||||||
|
return FreeImagePresent;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 *LoadImageWithFreeImage(FIMEMORY *fi, int *x, int *y, int *n, int n_req)
|
uint8 *LoadImageWithFreeImage(FIMEMORY *fi, int *x, int *y, int *n, int n_req)
|
||||||
{
|
{
|
||||||
uint8 *Result = 0;
|
uint8 *Result = 0;
|
||||||
FREE_IMAGE_FORMAT FileFormat = FreeImage_GetFileTypeFromMemory(fi, 0);
|
FREE_IMAGE_FORMAT FileFormat = FreeImage_GetFileTypeFromMemory(fi, 0);
|
||||||
FIBITMAP *Bitmap;
|
FIBITMAP *Bitmap;
|
||||||
if(FileFormat == -1)
|
if(FileFormat == -1) {
|
||||||
{
|
// @TODO: propogate the filename to here?
|
||||||
// @TODO: propogate the filename to here
|
// bail!
|
||||||
// bail!
|
return NULL;
|
||||||
return NULL;
|
// FileFormat = FreeImage_GetFIFFromFilename(FromFilename);
|
||||||
// FileFormat = FreeImage_GetFIFFromFilename(FromFilename);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
FreeImage_SeekMemory(fi, 0, SEEK_SET);
|
FreeImage_SeekMemory(fi, 0, SEEK_SET);
|
||||||
|
|
||||||
Bitmap = FreeImage_LoadFromMemory(FileFormat, fi, 0);
|
Bitmap = FreeImage_LoadFromMemory(FileFormat, fi, 0);
|
||||||
if(Bitmap)
|
if(Bitmap) {
|
||||||
{
|
int32 Width = FreeImage_GetWidth(Bitmap);
|
||||||
int32 Width = FreeImage_GetWidth(Bitmap);
|
int32 Height = FreeImage_GetHeight(Bitmap);
|
||||||
int32 Height = FreeImage_GetHeight(Bitmap);
|
|
||||||
|
|
||||||
Result = (uint8 *) malloc(Width * Height * BPP);
|
Result = (uint8 *) malloc(Width * Height * BPP);
|
||||||
if(Result)
|
if(Result) {
|
||||||
{
|
int i;
|
||||||
int i;
|
FreeImage_ConvertToRawBits(Result, Bitmap, BPP*Width, BPP*8, 0xff0000,0x00ff00,0xff, FALSE);
|
||||||
FreeImage_ConvertToRawBits(Result, Bitmap, BPP*Width, BPP*8, 0xff0000,0x00ff00,0xff, FALSE);
|
for (i=0; i < Width*Height*BPP; i += BPP) {
|
||||||
#ifndef PERFTEST
|
uint8 t = Result[i];
|
||||||
for (i=0; i < Width*Height*BPP; i += BPP) {
|
Result[i] = Result[i+2];
|
||||||
uint8 t = Result[i];
|
Result[i+2] = t;
|
||||||
Result[i] = Result[i+2];
|
|
||||||
Result[i+2] = t;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*x = Width;
|
|
||||||
*y = Height;
|
|
||||||
*n = FreeImage_IsTransparent(Bitmap) ? 4 : 3;
|
|
||||||
}
|
}
|
||||||
|
*x = Width;
|
||||||
FreeImage_Unload(Bitmap);
|
*y = Height;
|
||||||
}
|
*n = FreeImage_IsTransparent(Bitmap) ? 4 : 3;
|
||||||
|
}
|
||||||
return(Result);
|
FreeImage_Unload(Bitmap);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8 *imv_decode_from_memory(uint8 *mem, int len, int *x, int *y, int *n, int n_req)
|
static uint8 *imv_decode_from_memory(uint8 *mem, int len, int *x, int *y, int *n, int n_req)
|
||||||
{
|
{
|
||||||
uint8 *res = NULL;
|
uint8 *res = NULL;
|
||||||
|
imv_failure_string = NULL;
|
||||||
|
|
||||||
#ifdef USE_FREEIMAGE
|
#ifdef USE_FREEIMAGE
|
||||||
if (!only_stbi) {
|
if (!only_stbi) {
|
||||||
if (res == NULL && FreeImagePresent) {
|
if (res == NULL && FreeImagePresent) {
|
||||||
|
@ -3168,5 +3178,7 @@ static uint8 *imv_decode_from_memory(uint8 *mem, int len, int *x, int *y, int *n
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
res = stbi_load_from_memory(mem, len, x, y, n, n_req);
|
res = stbi_load_from_memory(mem, len, x, y, n, n_req);
|
||||||
|
if (res == NULL && imv_failure_string == NULL)
|
||||||
|
imv_failure_string = stbi_failure_reason();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
Version 0.94: Beta 5
|
||||||
|
* (bugfix: fix cacheing code to allow refreshing current image after flip etc.)
|
||||||
|
* (feature: use 'f' to flip image vertically, in case FreeImage sucks)
|
||||||
|
* change: change the border control keys to 'b' instead of 'f' for next feature
|
||||||
|
* feature: use FreeImage.dll if it's available
|
||||||
|
* bugfix: fix bug in right or bottom cursor region due to internal cleanup
|
||||||
|
|
||||||
Version 0.93: Beta 4
|
Version 0.93: Beta 4
|
||||||
* bugfix: alter stb_image to support jpegs with weird header blocks
|
* bugfix: alter stb_image to support jpegs with weird header blocks
|
||||||
* bugfix: exit after printing directory error message
|
* bugfix: exit after printing directory error message
|
||||||
|
|
|
@ -55,7 +55,7 @@ BSC32=bscmake.exe
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib advapi32.lib /nologo /subsystem:windows /machine:I386
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /machine:I386
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "stb_imv - Win32 Debug"
|
!ELSEIF "$(CFG)" == "stb_imv - Win32 Debug"
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ BSC32=bscmake.exe
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "stb_imv - Win32 Debug Opt"
|
!ELSEIF "$(CFG)" == "stb_imv - Win32 Debug Opt"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,22 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
Project: "stb_imv"=".\vc6\stb_imv.dsp" - Package Owner=<4>
|
Project: "install"="..\install\install.dsp" - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name stb_imv
|
||||||
|
End Project Dependency
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "stb_imv"=".\stb_imv.dsp" - Package Owner=<4>
|
||||||
|
|
||||||
Package=<5>
|
Package=<5>
|
||||||
{{{
|
{{{
|
||||||
|
|
Loading…
Reference in New Issue