![]() |
|
Loading an image from memory? |
endeavormac
Member #12,241
September 2010
|
Is there something along the lines of load_image(void * data, int length) that would allow me to send the data from a support image filetype without having to first save the image to the hdd? When sending these images over a network, it seems somewhat painful to first have to save them to the disk, and then load them from there. |
kazzmir
Member #1,786
December 2001
![]() |
In Allegro4 you can create a packfile out of memory and use the load_XX_pf routines. Here is my in-memory packfile you can use and a usage of loading PCX files. 1#include <allegro.h>
2
3namespace Memory{
4 struct memory{
5 memory(unsigned char * stream, int length):
6 stream(stream),
7 position(stream),
8 length(length){
9 }
10
11 int getSize() const {
12 return position - stream;
13 }
14
15 /* points to the head */
16 unsigned char * stream;
17 /* points to the current position */
18 unsigned char * position;
19 int length;
20 };
21
22 static int pf_fclose(void *userdata){
23 return 0;
24 /* nothing */
25 }
26
27 static int pf_getc(void *userdata){
28 memory * m = (memory*) userdata;
29 if (m->position < m->stream + m->length){
30 unsigned char x = *m->position;
31 m->position += 1;
32 return x;
33 }
34 return EOF;
35 }
36
37 static int pf_ungetc(int c, void *userdata){
38 memory * m = (memory*) userdata;
39 if (m->position > m->stream){
40 m->position -= 1;
41 return c;
42 } else {
43 return EOF;
44 }
45 }
46
47 static long pf_fread(void *p, long n, void *userdata){
48 memory *m = (memory*) userdata;
49 unsigned char *cp = (unsigned char *)p;
50 long i;
51 int c;
52
53 for (i=0; i<n; i++) {
54 if ((c = pf_getc(m)) == EOF)
55 break;
56
57 *(cp++) = c;
58 }
59
60 return i;
61 }
62
63 static int pf_putc(int c, void *userdata){
64 memory * m = (memory*) userdata;
65 if (m->position < m->stream + m->length){
66 *m->position = c;
67 m->position += 1;
68 return c;
69 }
70 return EOF;
71
72 }
73
74 static long pf_fwrite(const void *p, long n, void *userdata){
75 memory *m = (memory*) userdata;
76 const unsigned char * cp = (const unsigned char *) p;
77 long i;
78 int c;
79
80 /* probably should replace this with memcpy */
81
82 for (i=0; i<n; i++) {
83 if ((c = pf_putc(cp[i], userdata)) == EOF)
84 break;
85 }
86
87 return i;
88 }
89
90 static int pf_fseek(void *userdata, int offset){
91 memory * m = (memory*) userdata;
92 if (offset >= 0 && m->position + offset < m->stream + m->length){
93 m->position += offset;
94 return 0;
95 } else {
96 return -1;
97 }
98 }
99
100 static int pf_feof(void *userdata){
101 memory * m = (memory*) userdata;
102 return m->position >= m->stream + m->length;
103 }
104
105 static int pf_ferror(void *userdata){
106 memory * m = (memory*) userdata;
107 return m->position < m->stream || m->position >= m->stream + m->length;
108 }
109
110 static PACKFILE_VTABLE makeTable(){
111 PACKFILE_VTABLE table;
112 table.pf_fclose = Memory::pf_fclose;
113 table.pf_getc = Memory::pf_getc;
114 table.pf_ungetc = Memory::pf_ungetc;
115 table.pf_fread = Memory::pf_fread;
116 table.pf_putc = Memory::pf_putc;
117 table.pf_fwrite = Memory::pf_fwrite;
118 table.pf_fseek = Memory::pf_fseek;
119 table.pf_feof = Memory::pf_feof;
120 table.pf_ferror = Memory::pf_ferror;
121 return table;
122 }
123}
BITMAP * memoryPCX(unsigned char * const data, const int length){ PACKFILE_VTABLE table = Memory::makeTable(); Memory::memory memory(data, length); PACKFILE * pack = pack_fopen_vtable(&table, &memory); /* need to supply a proper palette at some point */ RGB * palette = NULL; BITMAP * pcx = load_pcx_pf(pack, palette); pack_fclose(pack); return pcx; }
|
endeavormac
Member #12,241
September 2010
|
They really decided not to make it easy, huh. Thanks for the response. |
Bob
Free Market Evangelist
September 2000
![]() |
There's a simpler way if you can already extract the pixel data from memory. kazzmir's method is great if you have a file loaded in memory, especially one with a non-trivial format. -- |
|