void load_examples(const void *data, size_t len, example_list_t *examples) { example_patch_t *patch; struct archive *arch; struct archive_entry *ent; const char *path; FILE *fp; char *buf; size_t size; char block[4096]; ssize_t count; int ret; assert(data != NULL); arch = archive_read_new(); assert(arch != NULL); if (archive_read_support_format_zip(arch)) abort(); if (archive_read_open_memory(arch, (void *) data, len)) abort(); while (!(ret = archive_read_next_header(arch, &ent))) { if (!S_ISREG(archive_entry_filetype(ent))) continue; path = archive_entry_pathname(ent); if (strncmp(path, EXAMPLE_DIR "/", strlen(EXAMPLE_DIR) + 1)) continue; /* archive_entry_size() is not reliable for Zip files */ fp = open_memstream(&buf, &size); if (fp == NULL) abort(); while ((count = archive_read_data(arch, block, sizeof(block))) > 0) if (fwrite(block, 1, count, fp) != (size_t) count) abort(); if (count < 0) { fprintf(stderr, "%s\n", archive_error_string(arch)); abort(); } fclose(fp); patch = malloc(sizeof(*patch)); patch->image = read_rgb_image(buf, size); if (patch->image == NULL) { fprintf(stderr, "Couldn't decode example %s\n", path); abort(); } TAILQ_INSERT_TAIL(examples, patch, link); free(buf); } assert(ret == ARCHIVE_EOF); if (archive_read_finish(arch)) abort(); }
// XIMG and similar formats. // TODO: Should this function be merged with do_gem_img()? static int do_gem_ximg(deark *c, lctx *d) { dbuf *unc_pixels = NULL; de_bitmap *img = NULL; de_finfo *fi = NULL; int retval = 0; int saved_indent_level; de_dbg_indent_save(c, &saved_indent_level); de_dbg(c, "header (continued) at %d", 8*2); de_dbg_indent(c, 1); if((d->nplanes>=1 && d->nplanes<=8) /* || d->nplanes==24 */) { ; } else { if(d->is_ximg) de_err(c, "%d-plane XIMG images are not supported", (int)d->nplanes); else de_err(c, "This type of %d-plane image is not supported", (int)d->nplanes); goto done; } if(d->header_size_in_words==25 && !d->is_ximg) { i64 pal_pos = d->header_size_in_bytes-32; de_dbg(c, "palette at %d", (int)pal_pos); de_dbg_indent(c, 1); de_fmtutil_read_atari_palette(c, c->infile, pal_pos, d->pal, 16, ((i64)1)<<d->nplanes, 0); de_dbg_indent(c, -1); } else { read_palette_ximg(c, d); } if(d->nplanes==1 && d->pal[0]==d->pal[1]) { de_dbg(c, "Palette doesn't seem to be present. Using a default palette."); d->pal[0] = DE_STOCKCOLOR_WHITE; d->pal[1] = DE_STOCKCOLOR_BLACK; } de_dbg_indent(c, -1); de_dbg(c, "image at %d", (int)d->header_size_in_bytes); unc_pixels = dbuf_create_membuf(c, d->rowspan_total*d->h, 0); uncompress_pixels(c, d, unc_pixels, d->header_size_in_bytes, c->infile->len-d->header_size_in_bytes); img = de_bitmap_create(c, d->w, d->h, 3); fi = de_finfo_create(c); set_density(c, d, fi); if(d->nplanes>8) { read_rgb_image(c, d, unc_pixels, img); } else { read_paletted_image(c, d, unc_pixels, img); } de_bitmap_write_to_file_finfo(img, fi, 0); retval = 1; done: de_bitmap_destroy(img); de_finfo_destroy(c, fi); dbuf_close(unc_pixels); de_dbg_indent_restore(c, saved_indent_level); return retval; }