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

Reply via email to