On Monday 16 July 2007 12:26:51 Hisham Mardam Bey wrote:
> On 7/15/07, Eric Wasylishen <[EMAIL PROTECTED]> wrote:
> > Hi, I have a few questions related image loading.
> >
> > One thing I'm working on is an xmms2 client using ETK/evolve. I'd like
> > it to show album cover art; the way the xmms2 client lib handles this
> > is it gives you a pointer to an image file that was copied in to
> > memory but not decoded. People using gtk have a function in gdk_pixbuf
> > for this, which automatically determines the image format (probably
> > jpg or png for covers) and decodes it, but as far as I can tell
> > imlib2/evas lack this feature? (though I noticed epeg can load a jpeg
> > file from memory.)
> >
> > One option I though of is just copying the loader code for say JPG and
> > PNG from evas or imlib2 in to my app, and modifying it to do what I
> > need. Or, would loading images from memory be useful enough to go in
> > evas or imlib2?
>
> Would be nice to have in evas.
Definitively. I started looking at this and only wrote a patch for eet. This
patch add a new eet_memopen_read. So you can add eet file also to your
idea :)
Cedric
--- e17-clean/libs/eet/src/lib/eet_lib.c 2007-07-04 15:00:23.000000000 +0200
+++ e17-dev/libs/eet/src/lib/eet_lib.c 2007-07-04 15:02:25.000000000 +0200
@@ -464,21 +464,207 @@
num++;
}
}
-
+
for (i = 0; i < num; i++)
eet_close(closelist[i]);
}
}
+static Eet_File*
+eet_internal_read (Eet_File *ef)
+{
+ const uint8_t *dyn_buf = NULL;
+ const uint8_t *p = NULL;
+ int index = 0;
+ int num_entries;
+ int byte_entries;
+ int i;
+
+ if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef))
+ return NULL;
+
+ /* build header table if read mode */
+ /* geat header */
+ index += sizeof(int);
+ if (eet_test_close((int)ntohl(*((int *)ef->data)) != EET_MAGIC_FILE, ef))
+ return NULL;
+
+#define EXTRACT_INT(Value, Pointer, Index) \
+ { \
+ int tmp; \
+ memcpy(&tmp, Pointer + Index, sizeof(int)); \
+ Value = ntohl(tmp); \
+ Index += sizeof(int); \
+ }
+
+ /* get entries count and byte count */
+ EXTRACT_INT(num_entries, ef->data, index);
+ EXTRACT_INT(byte_entries, ef->data, index);
+
+ /* we cant have <= 0 values here - invalid */
+ if (eet_test_close((num_entries <= 0) || (byte_entries <= 0), ef))
+ return NULL;
+
+ /* we can't have more entires than minimum bytes for those! invalid! */
+ if (eet_test_close((num_entries * 20) > byte_entries, ef))
+ return NULL;
+
+ /* allocate header */
+ ef->header = malloc(sizeof(Eet_File_Header));
+ if (eet_test_close(!ef->header, ef))
+ return NULL;
+
+ ef->header->magic = EET_MAGIC_FILE_HEADER;
+
+ /* allocate directory block in ram */
+ ef->header->directory = malloc(sizeof(Eet_File_Directory));
+ if (eet_test_close(!ef->header->directory, ef))
+ return NULL;
+
+ /* 8 bit hash table (256 buckets) */
+ ef->header->directory->size = 8;
+ /* allocate base hash table */
+ ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
+ if (eet_test_close(!ef->header->directory->nodes, ef))
+ return NULL;
+
+ /* actually read the directory block - all of it, into ram */
+ dyn_buf = ef->data + index;
+
+ /* parse directory block */
+ p = dyn_buf;
+
+ for (i = 0; i < num_entries; i++)
+ {
+ Eet_File_Node *efn;
+ void *data = NULL;
+ int indexn = 0;
+ int name_size;
+ int hash;
+ int k;
+
+#define HEADER_SIZE (sizeof(int) * 5)
+
+ /* out directory block is inconsistent - we have oveerun our */
+ /* dynamic block buffer before we finished scanning dir entries */
+ if (eet_test_close(p + HEADER_SIZE >= (dyn_buf + byte_entries), ef))
+ return NULL;
+
+ /* allocate all the ram needed for this stored node accounting */
+ efn = malloc (sizeof(Eet_File_Node));
+ if (eet_test_close(!efn, ef))
+ return NULL;
+
+ /* get entrie header */
+ EXTRACT_INT(efn->offset, p, indexn);
+ EXTRACT_INT(efn->compression, p, indexn);
+ EXTRACT_INT(efn->size, p, indexn);
+ EXTRACT_INT(efn->data_size, p, indexn);
+ EXTRACT_INT(name_size, p, indexn);
+
+ /* invalid size */
+ if (eet_test_close(efn->size <= 0, ef))
+ {
+ free (efn);
+ return NULL;
+ }
+
+ /* invalid name_size */
+ if (eet_test_close(name_size <= 0, ef))
+ {
+ free (efn);
+ return NULL;
+ }
+
+ /* reading name would mean falling off end of dyn_buf - invalid */
+ if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef))
+ {
+ free (efn);
+ return NULL;
+ }
+
+ /* This code is useless if we dont want backward compatibility */
+ for (k = name_size; k > 0 && ((uint8_t) * (p + HEADER_SIZE + k)) != 0; --k)
+ ;
+
+ efn->free_name = ((uint8_t) * (p + HEADER_SIZE + k)) != 0;
+
+ if (efn->free_name)
+ {
+ efn->name = malloc(sizeof(char) * name_size + 1);
+ if (eet_test_close(efn->name == NULL, ef))
+ {
+ free (efn);
+ return NULL;
+ }
+
+ strncpy(efn->name, (char *)p + HEADER_SIZE, name_size);
+ efn->name[name_size] = 0;
+
+ printf("File: %s is not up to date for key \"%s\" - needs rebuilding sometime\n", ef->path, efn->name);
+ }
+ else
+ /* The only really usefull peace of code for efn->name (no backward compatibility) */
+ efn->name = (char*)((uint8_t*)(p + HEADER_SIZE));
+
+ /* get hash bucket it should go in */
+ hash = _eet_hash_gen(efn->name, ef->header->directory->size);
+ efn->next = ef->header->directory->nodes[hash];
+ ef->header->directory->nodes[hash] = efn;
+
+ /* read-only mode, so currently we have no data loaded */
+ if (ef->mode == EET_FILE_MODE_READ)
+ efn->data = NULL;
+ /* read-write mode - read everything into ram */
+ else
+ {
+ data = malloc(efn->size);
+ if (data)
+ memcpy(data, ef->data + efn->offset, efn->size);
+ efn->data = data;
+ }
+ /* advance */
+ p += HEADER_SIZE + name_size;
+ }
+ return ef;
+}
+
+EAPI Eet_File *
+eet_memopen_read(const void *data, size_t size)
+{
+ Eet_File *ef;
+
+ if (data == NULL || size == 0)
+ return NULL;
+
+ ef = malloc (sizeof (Eet_File));
+ if (!ef)
+ return NULL;
+
+ ef->path = NULL;
+ ef->magic = EET_MAGIC_FILE;
+ ef->references = 1;
+ ef->mode = EET_FILE_MODE_READ;
+ ef->header = NULL;
+ ef->mtime = 0;
+ ef->delete_me_now = 1;
+ ef->fp = NULL;
+ ef->data = data;
+ ef->data_size = size;
+
+ return eet_internal_read(ef);
+}
+
EAPI Eet_File *
eet_open(const char *file, Eet_File_Mode mode)
{
Eet_File *ef;
struct stat file_stat;
+
#ifdef _WIN32
HANDLE h;
#endif
-
+
if (!file)
return NULL;
@@ -577,12 +763,6 @@
/* if we opened for read or read-write */
if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
{
- unsigned char *dyn_buf = NULL;
- unsigned char *p = NULL;
- int index = 0;
- int num_entries;
- int byte_entries;
- int i;
#ifdef _WIN32
HANDLE fm;
#endif
@@ -607,152 +787,9 @@
CloseHandle(fm);
#endif
- if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef))
- return NULL;
-
- /* build header table if read mode */
- /* geat header */
- index += sizeof(int);
- if (eet_test_close((int)ntohl(*((int *)ef->data)) != EET_MAGIC_FILE, ef))
- return NULL;
-
-#define EXTRACT_INT(Value, Pointer, Index) \
- { \
- int tmp; \
- memcpy(&tmp, Pointer + Index, sizeof(int)); \
- Value = ntohl(tmp); \
- Index += sizeof(int); \
- }
-
- /* get entries count and byte count */
- EXTRACT_INT(num_entries, ef->data, index);
- EXTRACT_INT(byte_entries, ef->data, index);
-
- /* we cant have <= 0 values here - invalid */
- if (eet_test_close((num_entries <= 0) || (byte_entries <= 0), ef))
- return NULL;
-
- /* we can't have more entires than minimum bytes for those! invalid! */
- if (eet_test_close((num_entries * 20) > byte_entries, ef))
- return NULL;
-
- /* allocate header */
- ef->header = calloc(1, sizeof(Eet_File_Header));
- if (eet_test_close(!ef->header, ef))
- return NULL;
-
- ef->header->magic = EET_MAGIC_FILE_HEADER;
-
- /* allocate directory block in ram */
- ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
- if (eet_test_close(!ef->header->directory, ef))
- return NULL;
-
- /* 8 bit hash table (256 buckets) */
- ef->header->directory->size = 8;
- /* allocate base hash table */
- ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
- if (eet_test_close(!ef->header->directory->nodes, ef))
+ ef = eet_internal_read(ef);
+ if (!ef)
return NULL;
-
- /* actually read the directory block - all of it, into ram */
- dyn_buf = ef->data + index;
-
- /* parse directory block */
- p = dyn_buf;
-
- for (i = 0; i < num_entries; i++)
- {
- Eet_File_Node *efn;
- void *data = NULL;
- int indexn = 0;
- int name_size;
- int hash;
- int k;
-
-#define HEADER_SIZE (sizeof(int) * 5)
-
- /* out directory block is inconsistent - we have oveerun our */
- /* dynamic block buffer before we finished scanning dir entries */
- if (eet_test_close(p + HEADER_SIZE >= (dyn_buf + byte_entries), ef))
- return NULL;
-
- /* allocate all the ram needed for this stored node accounting */
- efn = malloc (sizeof(Eet_File_Node));
- if (eet_test_close(!efn, ef))
- return NULL;
-
- /* get entrie header */
- EXTRACT_INT(efn->offset, p, indexn);
- EXTRACT_INT(efn->compression, p, indexn);
- EXTRACT_INT(efn->size, p, indexn);
- EXTRACT_INT(efn->data_size, p, indexn);
- EXTRACT_INT(name_size, p, indexn);
-
- /* invalid size */
- if (eet_test_close(efn->size <= 0, ef))
- {
- free (efn);
- return NULL;
- }
-
- /* invalid name_size */
- if (eet_test_close(name_size <= 0, ef))
- {
- free (efn);
- return NULL;
- }
-
- /* reading name would mean falling off end of dyn_buf - invalid */
- if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef))
- {
- free (efn);
- return NULL;
- }
-
- /* This code is useless if we dont want backward compatibility */
- for (k = name_size; k > 0 && ((uint8_t) * (p + HEADER_SIZE + k)) != 0; --k)
- ;
-
- efn->free_name = ((uint8_t) * (p + HEADER_SIZE + k)) != 0;
-
- if (efn->free_name)
- {
- efn->name = malloc(sizeof(char) * name_size + 1);
- if (eet_test_close(efn->name == NULL, ef))
- {
- free (efn);
- return NULL;
- }
-
- strncpy(efn->name, (char *)p + HEADER_SIZE, name_size);
- efn->name[name_size] = 0;
-
- printf("File: %s is not up to date for key \"%s\" - needs rebuilding sometime\n", ef->path, efn->name);
- }
- else
- /* The only really usefull peace of code for efn->name (no backward compatibility) */
- efn->name = (char*)((uint8_t*)(p + HEADER_SIZE));
-
- /* get hash bucket it should go in */
- hash = _eet_hash_gen(efn->name, ef->header->directory->size);
- efn->next = ef->header->directory->nodes[hash];
- ef->header->directory->nodes[hash] = efn;
-
- /* read-only mode, so currently we have no data loaded */
- if (mode == EET_FILE_MODE_READ)
- efn->data = NULL;
- /* read-write mode - read everything into ram */
- else
- {
- data = malloc(efn->size);
- if (data)
- memcpy(data, ef->data + efn->offset, efn->size);
- efn->data = data;
- }
- /* advance */
- p += HEADER_SIZE + name_size;
- }
}
/* we need to delete the original file in read-write mode and re-open for writing */
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel