166 lines
4.9 KiB
C
166 lines
4.9 KiB
C
// generate thumbnail for images
|
|
#include "thumb.h"
|
|
|
|
// XXX: can do progressive resize down ie scale to 512 then take 512 and
|
|
// halve to 256 then halve it to 128 etc. rather than render from orig to
|
|
// target size....
|
|
|
|
static Evas_Object *im = NULL;
|
|
static Eina_Bool alpha = EINA_FALSE;
|
|
static int iw = 0, ih = 0;
|
|
|
|
static void
|
|
_thumb_image_setup(void)
|
|
{ // create and show image
|
|
im = evas_object_image_filled_add(evas_object_evas_get(subwin));
|
|
evas_object_show(im);
|
|
}
|
|
|
|
static void
|
|
_thumb_image_file_set(const char *file)
|
|
{ // set file to image, get size & alpha
|
|
evas_object_image_file_set(im, file, NULL);
|
|
evas_object_image_size_get(im, &iw, &ih);
|
|
alpha = evas_object_image_alpha_get(im);
|
|
}
|
|
|
|
static void
|
|
_thumb_image_hsv_sort_render(unsigned int *dst, int w, int h)
|
|
{ // render image down to a specific size (small) and copy to dest
|
|
void *pixels;
|
|
|
|
evas_object_resize(im, w, h);
|
|
evas_object_resize(subwin, w, h);
|
|
elm_win_render(subwin);
|
|
pixels = evas_object_image_data_get(image, EINA_FALSE);
|
|
if (!pixels) return;
|
|
memcpy(dst, pixels, w * h * sizeof(int));
|
|
evas_object_image_data_set(image, pixels);
|
|
}
|
|
|
|
static void
|
|
_thumb_image_hsv_sort_key_write(Eet_File *ef, const char *key)
|
|
{ // get rendered pixels from image representing subwin and write out AHVS key
|
|
unsigned int *data4x4, *data2x2, *data1x1;
|
|
unsigned char id2[256];
|
|
int n, i, hi, si, vi;
|
|
float h, s, v;
|
|
const int pat2x2[4] = { 0, 3, 1, 2 };
|
|
const int pat4x4[16] = { 5, 10, 6, 9,
|
|
0, 15, 3, 12,
|
|
1, 14, 7, 8,
|
|
4, 11, 2, 13 };
|
|
|
|
data4x4 = malloc(4 * 4 * sizeof(int));
|
|
data2x2 = malloc(2 * 2 * sizeof(int));
|
|
data1x1 = malloc(1 * 1 * sizeof(int));
|
|
|
|
if ((!data4x4) || (!data2x2) || (!data1x1)) goto err;
|
|
|
|
_thumb_image_hsv_sort_render(data4x4, 4, 4);
|
|
_thumb_image_hsv_sort_render(data2x2, 2, 2);
|
|
_thumb_image_hsv_sort_render(data1x1, 1, 1);
|
|
|
|
n = 0;
|
|
|
|
#define A(v) (((v) >> 24) & 0xff)
|
|
#define R(v) (((v) >> 16) & 0xff)
|
|
#define G(v) (((v) >> 8 ) & 0xff)
|
|
#define B(v) (((v) ) & 0xff)
|
|
#define HSV(p) do { \
|
|
evas_color_rgb_to_hsv(R(p), G(p), B(p), &h, &s, &v); \
|
|
hi = 20 * (h / 360.0); \
|
|
si = 20 * s; \
|
|
vi = 20 * v; \
|
|
if (si < 2) hi = 25; \
|
|
} while (0)
|
|
#define SAVEX(x) id2[n++] = 'a' + (x)
|
|
|
|
SAVEX(A(data1x1[0]));
|
|
for (i = 0; i < 4 ; i++) SAVEX(A(data2x2[pat2x2[i]]));
|
|
for (i = 0; i < 16; i++) SAVEX(A(data4x4[pat4x4[i]]));
|
|
|
|
#define STORE(val) \
|
|
HSV(data1x1[0]); \
|
|
SAVEX(val); \
|
|
for (i = 0; i < 4; i++) { \
|
|
HSV(data2x2[pat2x2[i]]); \
|
|
SAVEX(val); \
|
|
} \
|
|
for (i = 0; i < 16; i++) { \
|
|
HSV(data4x4[pat4x4[i]]); \
|
|
SAVEX(val); \
|
|
}
|
|
|
|
STORE(hi);
|
|
STORE(vi);
|
|
STORE(si);
|
|
|
|
id2[n++] = 0;
|
|
|
|
eet_write(ef, key, id2, n,
|
|
EET_COMPRESSION_NONE);
|
|
err:
|
|
free(data4x4);
|
|
free(data2x2);
|
|
free(data1x1);
|
|
}
|
|
|
|
int
|
|
thumb_image(Eet_File *ef, const char *path, const char *mime EINA_UNUSED, const char *thumb EINA_UNUSED)
|
|
{
|
|
const int sizes[] = { 512, 256, 128, 64, 32, 16, 0 };
|
|
int w, h, i;
|
|
char buf[128];
|
|
unsigned char a;
|
|
|
|
_thumb_image_setup();
|
|
// add filled image to then size accordingly
|
|
_thumb_image_file_set(path);
|
|
// if size is bunk - we can't load it...
|
|
if ((iw <= 0) || (ih < 0)) return 2;
|
|
|
|
// write a big 1024x1024 preview (but no larger than the original image)
|
|
w = iw; h = ih; scale(&w, &h, 1024, 1024, EINA_TRUE);
|
|
|
|
// resize to target size
|
|
evas_object_resize(im, w, h);
|
|
evas_object_resize(subwin, w, h);
|
|
// render our current state and pick up pixel results
|
|
elm_win_render(subwin);
|
|
// save out preview size
|
|
snprintf(buf, sizeof(buf), "image/preview");
|
|
thumb_image_write(ef, buf, image, alpha, EINA_TRUE);
|
|
snprintf(buf, sizeof(buf), "%i %i", w, h);
|
|
eet_write(ef, "image/preview/size", buf, strlen(buf) + 1,
|
|
EET_COMPRESSION_NONE);
|
|
|
|
// multiple thumb sizes so can load/pick the best one at runtime
|
|
for (i = 0; sizes[i] != 0; i++)
|
|
{
|
|
// scale down and keep aspect
|
|
w = iw; h = ih; scale(&w, &h, sizes[i], sizes[i], EINA_FALSE);
|
|
// resize to target size
|
|
evas_object_resize(im, w, h);
|
|
evas_object_resize(subwin, w, h);
|
|
// render our current state and pick up pixel results
|
|
elm_win_render(subwin);
|
|
// save out thumb size
|
|
snprintf(buf, sizeof(buf), "image/thumb/%i", sizes[i]);
|
|
thumb_image_write(ef, buf, image, alpha, EINA_TRUE);
|
|
}
|
|
|
|
_thumb_image_hsv_sort_key_write(ef, "image/sort_key");
|
|
|
|
// write original alpha flag
|
|
a = alpha;
|
|
if (alpha)
|
|
eet_write(ef, "orig/image/alpha", &a, 1,
|
|
EET_COMPRESSION_NONE);
|
|
// write original size
|
|
snprintf(buf, sizeof(buf), "%i %i", iw, ih);
|
|
eet_write(ef, "orig/image/size", buf, strlen(buf) + 1,
|
|
EET_COMPRESSION_NONE);
|
|
return 0;
|
|
}
|