10 int load_image(struct image *img, const char *fname)
14 uint16_t width, height;
16 memset(img, 0, sizeof *img);
18 if(!(fp = fopen(fname, "rb"))) {
19 fprintf(stderr, "load_image: failed to open file: %s: %s\n", fname, strerror(errno));
22 if(fread(sig, 1, 8, fp) < 8) {
23 fprintf(stderr, "unexpected EOF while reading: %s\n", fname);
28 if(memcmp(sig, "IDUMP565", 8) != 0) {
32 /* it's a 565 dump, read it and return */
33 if(!fread(&width, 2, 1, fp) || !fread(&height, 2, 1, fp)) {
34 fprintf(stderr, "unexpected EOF while reading: %s\n", fname);
38 #ifdef BUILD_BIGENDIAN
39 width = BSWAP16(width);
40 height = BSWAP16(height);
43 if(!(img->pixels = malloc(width * height * 2))) {
44 fprintf(stderr, "failed to allocate %dx%d pixel buffer for %s\n", width, height, fname);
48 if(fread(img->pixels, 2, width * height, fp) < width * height) {
49 fprintf(stderr, "unexpected EOF while reading: %s\n", fname);
56 #ifdef BUILD_BIGENDIAN
58 int i, npix = width * height;
59 for(i=0; i<npix; i++) {
60 uint16_t p = img->pixels[i];
61 img->pixels[i] = BSWAP16(p);
73 if(memcmp(sig, "animtex", 7) == 0) {
74 /* it's an animated texture. read metadata, and recurse with the new name*/
75 struct ts_node *root, *node;
77 int fps, num_frames = 0;
79 if(!(root = ts_load(fname))) {
80 fprintf(stderr, "failed to load animation %s\n", fname);
83 if(!(imgfname = ts_lookup_str(root, "animtex.image", 0))) {
84 fprintf(stderr, "animtex %s missing `image` attribute\n", fname);
88 if(strcmp(imgfname, fname) == 0) {
89 fprintf(stderr, "animtex %s is silly...\n", fname);
94 if(load_image(img, imgfname) == -1) {
99 fps = ts_lookup_int(root, "animtex.framerate", 25);
100 img->frame_interval = 1.0f / (float)fps;
103 node = root->child_list;
105 if(strcmp(node->name, "frame") == 0) {
111 if(!(img->uoffs = malloc(2 * num_frames * sizeof *img->uoffs))) {
112 fprintf(stderr, "animtex %s: failed to allocate uvoffset array for %d frames\n", fname, num_frames);
117 img->voffs = img->uoffs + num_frames;
120 node = root->child_list;
122 if(strcmp(node->name, "frame") == 0) {
123 float *v = ts_get_attr_vec(node, "uvoffset", 0);
125 img->uoffs[num_frames] = v[0];
126 img->voffs[num_frames++] = v[1];
128 fprintf(stderr, "animtex %s: ignoring frame without uvoffset\n", fname);
134 img->num_frames = num_frames;
140 /* just a regular image */
141 if(!(img->pixels = img_load_pixels(fname, &img->width, &img->height, IMG_FMT_RGB565))) {
142 fprintf(stderr, "failed to load image: %s\n", fname);
148 int dump_image(struct image *img, const char *fname)
151 uint16_t width, height;
153 #ifdef BUILD_BIGENDIAN
154 int i, npix = img->width * img->height;
155 width = BSWAP16(img->width);
156 height = BSWAP16(img->height);
159 height = img->height;
162 if(!(fp = fopen(fname, "wb"))) {
163 fprintf(stderr, "dump_image: failed to open %s: %s\n", fname, strerror(errno));
166 fwrite("IDUMP565", 1, 8, fp);
167 fwrite(&width, 2, 1, fp);
168 fwrite(&height, 2, 1, fp);
170 #ifdef BUILD_BIGENDIAN
171 for(i=0; i<npix; i++) {
172 uint16_t p = BSWAP16(img->pixels[i]);
173 fwrite(&p, 2, 1, fp);
176 fwrite(img->pixels, 2, img->width * img->height, fp);
182 void destroy_image(struct image *img)
185 img_free_pixels(img->pixels);
190 int load_cubemap(struct image *cube, const char *fname_fmt)
193 char dirstr[3] = {0};
197 dirstr[0] = i & 1 ? 'n' : 'p';
198 dirstr[1] = i < 2 ? 'x' : (i < 4 ? 'y' : 'z');
199 sprintf(fname, fname_fmt, dirstr);
200 if(load_image(cube + i, fname) == -1) {
202 destroy_image(cube + i);
210 void destroy_cubemap(struct image *cube)
217 destroy_image(cube + i);