int xmp_load_module(xmp_context opaque, char *path) { struct context_data *ctx = (struct context_data *)opaque; struct module_data *m = &ctx->m; HIO_HANDLE *h; struct stat st; struct list_head tmpfiles_list; D_(D_WARN "path = %s", path); if (stat(path, &st) < 0) return -XMP_ERROR_SYSTEM; #ifndef _MSC_VER if (S_ISDIR(st.st_mode)) { errno = EISDIR; return -XMP_ERROR_SYSTEM; } #endif if ((h = hio_open_file(path, "rb")) == NULL) return -XMP_ERROR_SYSTEM; INIT_LIST_HEAD(&tmpfiles_list); D_(D_INFO "decrunch"); if (decrunch(&tmpfiles_list, &h->f, &path, DECRUNCH_MAX) < 0) goto err_depack; if (hio_stat(h, &st) < 0) goto err_depack; if (st.st_size < 256) { /* get size after decrunch */ hio_close(h); unlink_tempfiles(&tmpfiles_list); return -XMP_ERROR_FORMAT; } if (ctx->state > XMP_STATE_UNLOADED) xmp_release_module(opaque); m->dirname = get_dirname(path); if (m->dirname == NULL) return -XMP_ERROR_SYSTEM; m->basename = get_basename(path); if (m->basename == NULL) return -XMP_ERROR_SYSTEM; m->filename = path; /* For ALM, SSMT, etc */ m->size = st.st_size; return load_module(opaque, h, &tmpfiles_list); err_depack: hio_close(h); unlink_tempfiles(&tmpfiles_list); return -XMP_ERROR_DEPACK; }
void decrunch_backwards(int level, struct membuf *inbuf, struct membuf *outbuf) { int outpos; reverse_buffer(membuf_get(inbuf), membuf_memlen(inbuf)); outpos = membuf_memlen(outbuf); decrunch(level, inbuf, outbuf); reverse_buffer(membuf_get(inbuf), membuf_memlen(inbuf)); reverse_buffer((char*)membuf_get(outbuf) + outpos, membuf_memlen(outbuf) - outpos); }
bool HDRLoader::load(const char *fileName, HDRLoaderResult &res) { int i; char str[200]; FILE *file; file = fopen(fileName, "rb"); if (!file) return false; fread(str, 10, 1, file); if (memcmp(str, "#?RADIANCE", 10)) { fclose(file); return false; } fseek(file, 1, SEEK_CUR); char cmd[200]; i = 0; char c = 0, oldc; while(true) { oldc = c; c = fgetc(file); if (c == 0xa && oldc == 0xa) break; cmd[i++] = c; } char reso[200]; i = 0; while(true) { c = fgetc(file); reso[i++] = c; if (c == 0xa) break; } int w, h; if (!sscanf(reso, "-Y %ld +X %ld", &h, &w)) { fclose(file); return false; } res.width = w; res.height = h; float *cols = new float[w * h * 3]; res.cols = cols; RGBE *scanline = new RGBE[w]; if (!scanline) { fclose(file); return false; } // convert image for (int y = h - 1; y >= 0; y--) { if (decrunch(scanline, w, file) == false) break; workOnRGBE(scanline, w, cols); cols += w * 3; } delete [] scanline; fclose(file); return true; }
static char get_char_from_msb_lsb(unsigned char msb, unsigned char lsb) { return decrunch((msb << 3) | lsb); }
int xmp_load_module(xmp_context opaque, char *path) { struct context_data *ctx = (struct context_data *)opaque; struct module_data *m = &ctx->m; HIO_HANDLE *h; struct stat st; struct list_head tmpfiles_list; int test_result, load_result; int i, ret; D_(D_WARN "path = %s", path); if (stat(path, &st) < 0) return -XMP_ERROR_SYSTEM; #ifndef _MSC_VER if (S_ISDIR(st.st_mode)) { errno = EISDIR; return -XMP_ERROR_SYSTEM; } #endif if ((h = hio_open_file(path, "rb")) == NULL) return -XMP_ERROR_SYSTEM; INIT_LIST_HEAD(&tmpfiles_list); D_(D_INFO "decrunch"); if (decrunch(&tmpfiles_list, &h->f, &path, DECRUNCH_MAX) < 0) goto err_depack; if (hio_stat(h, &st) < 0) goto err_depack; if (st.st_size < 256) { /* get size after decrunch */ hio_close(h); unlink_tempfiles(&tmpfiles_list); return -XMP_ERROR_FORMAT; } if (ctx->state > XMP_STATE_UNLOADED) xmp_release_module(opaque); m->dirname = get_dirname(path); if (m->dirname == NULL) return -XMP_ERROR_SYSTEM; m->basename = get_basename(path); if (m->basename == NULL) return -XMP_ERROR_SYSTEM; m->filename = path; /* For ALM, SSMT, etc */ m->size = st.st_size; load_prologue(ctx); D_(D_WARN "load"); test_result = load_result = -1; for (i = 0; format_loader[i] != NULL; i++) { hio_seek(h, 0, SEEK_SET); test_result = format_loader[i]->test(h, NULL, 0); if (test_result == 0) { hio_seek(h, 0, SEEK_SET); D_(D_WARN "load format: %s", format_loader[i]->name); load_result = format_loader[i]->loader(m, h, 0); break; } } set_md5sum(h, m->md5); hio_close(h); unlink_tempfiles(&tmpfiles_list); if (test_result < 0) { free(m->basename); free(m->dirname); return -XMP_ERROR_FORMAT; } if (load_result < 0) { xmp_release_module(opaque); return -XMP_ERROR_LOAD; } str_adj(m->mod.name); if (!*m->mod.name) { strncpy(m->mod.name, m->basename, XMP_NAME_SIZE); } load_epilogue(ctx); ret = prepare_scan(ctx); if (ret < 0) return ret; scan_sequences(ctx); ctx->state = XMP_STATE_LOADED; return 0; err_depack: hio_close(h); unlink_tempfiles(&tmpfiles_list); return -XMP_ERROR_DEPACK; }
static int decrunch(struct list_head *head, FILE **f, char **s, int ttl) { unsigned char b[1024]; char *cmd; FILE *t; int fd, builtin, res; char *temp2, tmp[PATH_MAX]; struct tmpfilename *temp; int headersize; cmd = NULL; builtin = res = 0; if (get_temp_dir(tmp, PATH_MAX) < 0) return 0; strncat(tmp, "xmp_XXXXXX", PATH_MAX); fseek(*f, 0, SEEK_SET); if ((headersize = fread(b, 1, 1024, *f)) < 100) /* minimum valid file size */ return 0; #if defined __AMIGA__ && !defined __AROS__ if (test_xfd(b, 1024)) { builtin = BUILTIN_XFD; } else #endif if (b[0] == 'P' && b[1] == 'K' && ((b[2] == 3 && b[3] == 4) || (b[2] == '0' && b[3] == '0' && b[4] == 'P' && b[5] == 'K' && b[6] == 3 && b[7] == 4))) { /* Zip */ builtin = BUILTIN_ZIP; } else if (b[2] == '-' && b[3] == 'l' && b[4] == 'h') { /* LHa */ builtin = BUILTIN_LHA; } else if (b[0] == 31 && b[1] == 139) { /* gzip */ builtin = BUILTIN_GZIP; } else if (b[0] == 'B' && b[1] == 'Z' && b[2] == 'h') { /* bzip2 */ builtin = BUILTIN_BZIP2; } else if (b[0] == 0xfd && b[3] == 'X' && b[4] == 'Z' && b[5] == 0x00) { /* xz */ builtin = BUILTIN_XZ; #if 0 } else if (b[0] == 'Z' && b[1] == 'O' && b[2] == 'O' && b[3] == ' ') { /* zoo */ builtin = BUILTIN_ZOO; #endif } else if (b[0] == 'M' && b[1] == 'O' && b[2] == '3') { /* MO3 */ cmd = "unmo3 -s \"%s\" STDOUT"; } else if (b[0] == 31 && b[1] == 157) { /* compress */ builtin = BUILTIN_COMPRESS; } else if (memcmp(b, "PP20", 4) == 0) { /* PowerPack */ builtin = BUILTIN_PP; } else if (memcmp(b, "XPKF", 4) == 0 && memcmp(b + 8, "SQSH", 4) == 0) { /* SQSH */ builtin = BUILTIN_SQSH; } else if (!memcmp(b, "Archive\0", 8)) { /* ArcFS */ builtin = BUILTIN_ARCFS; } else if (memcmp(b, "ziRCONia", 8) == 0) { /* MMCMP */ builtin = BUILTIN_MMCMP; } else if (memcmp(b, "MUSE", 4) == 0 && readmem32b(b + 4) == 0xdeadbeaf) { /* J2B MUSE */ builtin = BUILTIN_MUSE; } else if (memcmp(b, "MUSE", 4) == 0 && readmem32b(b + 4) == 0xdeadbabe) { /* MOD2J2B MUSE */ builtin = BUILTIN_MUSE; } else if (memcmp(b, "LZX", 3) == 0) { /* LZX */ builtin = BUILTIN_LZX; } else if (memcmp(b, "Rar", 3) == 0) { /* rar */ cmd = "unrar p -inul -xreadme -x*.diz -x*.nfo -x*.txt " "-x*.exe -x*.com \"%s\""; } else if (memcmp(b, "S404", 4) == 0) { /* Stonecracker */ builtin = BUILTIN_S404; } else if (test_oxm(*f) == 0) { /* oggmod */ builtin = BUILTIN_OXM; } if (builtin == 0 && cmd == NULL && b[0] == 0x1a) { int x = b[1] & 0x7f; int i, flag = 0; long size; /* check file name */ for (i = 0; i < 13; i++) { if (b[2 + i] == 0) { if (i == 0) /* name can't be empty */ flag = 1; break; } if (!isprint(b[2 + i])) { /* name must be printable */ flag = 1; break; } } size = readmem32l(b + 15); /* max file size is 512KB */ if (size < 0 || size > 512 * 1024) flag = 1; if (flag == 0) { if (x >= 1 && x <= 9 && x != 7) { /* Arc */ builtin = BUILTIN_ARC; } else if (x == 0x7f) { /* !Spark */ builtin = BUILTIN_ARC; } } } fseek(*f, 0, SEEK_SET); if (builtin == 0 && cmd == NULL) return 0; #if defined ANDROID || defined __native_client__ /* Don't use external helpers in android */ if (cmd) return 0; #endif D_(D_WARN "Depacking file... "); temp = calloc(sizeof (struct tmpfilename), 1); if (!temp) { D_(D_CRIT "calloc failed"); return -1; } temp->name = strdup(tmp); if (temp->name == NULL || (fd = mkstemp(temp->name)) < 0) { D_(D_CRIT "failed"); return -1; } list_add_tail(&temp->list, head); if ((t = fdopen(fd, "w+b")) == NULL) { D_(D_CRIT "failed"); return -1; } if (cmd) { #define BSIZE 0x4000 int n; char line[1024], buf[BSIZE]; FILE *p; snprintf(line, 1024, cmd, *s); #ifdef WIN32 /* Note: The _popen function returns an invalid file opaque, if * used in a Windows program, that will cause the program to hang * indefinitely. _popen works properly in a Console application. * To create a Windows application that redirects input and output, * read the section "Creating a Child Process with Redirected Input * and Output" in the Win32 SDK. -- Mirko */ if ((p = popen(line, "rb")) == NULL) { #else /* Linux popen fails with "rb" */ if ((p = popen(line, "r")) == NULL) { #endif D_(D_CRIT "failed"); fclose(t); return -1; } while ((n = fread(buf, 1, BSIZE, p)) > 0) fwrite(buf, 1, n, t); pclose (p); } else { switch (builtin) { case BUILTIN_PP: res = decrunch_pp(*f, t); break; case BUILTIN_ARC: res = decrunch_arc(*f, t); break; case BUILTIN_ARCFS: res = decrunch_arcfs(*f, t); break; case BUILTIN_SQSH: res = decrunch_sqsh(*f, t); break; case BUILTIN_MMCMP: res = decrunch_mmcmp(*f, t); break; case BUILTIN_MUSE: res = decrunch_muse(*f, t); break; case BUILTIN_LZX: res = decrunch_lzx(*f, t); break; case BUILTIN_S404: res = decrunch_s404(*f, t); break; case BUILTIN_ZIP: res = decrunch_zip(*f, t); break; case BUILTIN_GZIP: res = decrunch_gzip(*f, t); break; case BUILTIN_COMPRESS: res = decrunch_compress(*f, t); break; case BUILTIN_BZIP2: res = decrunch_bzip2(*f, t); break; case BUILTIN_XZ: res = decrunch_xz(*f, t); break; case BUILTIN_LHA: res = decrunch_lha(*f, t); break; #if 0 case BUILTIN_ZOO: res = decrunch_zoo(*f, t); break; #endif case BUILTIN_OXM: res = decrunch_oxm(*f, t); break; #ifdef AMIGA case BUILTIN_XFD: res = decrunch_xfd(*f, t); break; #endif } } if (res < 0) { D_(D_CRIT "failed"); fclose(t); return -1; } D_(D_INFO "done"); fclose(*f); *f = t; if (!--ttl) { return -1; } temp2 = strdup(temp->name); res = decrunch(head, f, &temp->name, ttl); free(temp2); /* Mirko: temp is now deallocated in unlink_tempfiles() * not a problem, since unlink_tempfiles() is called after decrunch * in loader routines * * free(temp); */ return res; } /* * Windows doesn't allow you to unlink an open file, so we changed the * temp file cleanup system to remove temporary files after we close it */ static void unlink_tempfiles(struct list_head *head) { struct tmpfilename *li; struct list_head *tmp; /* can't use list_for_each when freeing the node! */ for (tmp = head->next; tmp != head; ) { li = list_entry(tmp, struct tmpfilename, list); D_(D_INFO "unlink tmpfile %s", li->name); unlink(li->name); free(li->name); list_del(&li->list); tmp = tmp->next; free(li); } } int xmp_test_module(char *path, struct xmp_test_info *info) { HIO_HANDLE *h; struct stat st; char buf[XMP_NAME_SIZE]; int i; struct list_head tmpfiles_list; int ret = -XMP_ERROR_FORMAT;; if (stat(path, &st) < 0) return -XMP_ERROR_SYSTEM; #ifndef _MSC_VER if (S_ISDIR(st.st_mode)) { errno = EISDIR; return -XMP_ERROR_SYSTEM; } #endif if ((h = hio_open_file(path, "rb")) == NULL) return -XMP_ERROR_SYSTEM; INIT_LIST_HEAD(&tmpfiles_list); if (decrunch(&tmpfiles_list, &h->f, &path, DECRUNCH_MAX) < 0) { ret = -XMP_ERROR_DEPACK; goto err; } if (hio_stat(h, &st) < 0) {/* get size after decrunch */ ret = -XMP_ERROR_DEPACK; goto err; } if (st.st_size < 256) { /* set minimum valid module size */ ret = -XMP_ERROR_FORMAT; goto err; } if (info != NULL) { *info->name = 0; /* reset name prior to testing */ *info->type = 0; /* reset type prior to testing */ } for (i = 0; format_loader[i] != NULL; i++) { fseek(h->f, 0, SEEK_SET); if (format_loader[i]->test(h, buf, 0) == 0) { int is_prowizard = 0; if (strcmp(format_loader[i]->name, "prowizard") == 0) { fseek(h->f, 0, SEEK_SET); pw_test_format(h->f, buf, 0, info); is_prowizard = 1; } fclose(h->f); unlink_tempfiles(&tmpfiles_list); if (info != NULL && !is_prowizard) { strncpy(info->name, buf, XMP_NAME_SIZE); strncpy(info->type, format_loader[i]->name, XMP_NAME_SIZE); } return 0; } } err: hio_close(h); unlink_tempfiles(&tmpfiles_list); return ret; }
bool HDRLoader::load(const char *_fileName, const bool _rawRGBE, HDRLoaderResult &_res) { int i; char str[200]; FILE *file; file = osgDB::fopen(_fileName, "rb"); if (!file) return false; size_t numRead = fread(str, 10, 1, file); if (numRead < 1) { fclose(file); return false; } if (memcmp(str, "#?RADIANCE", 10)) { fseek(file, 0, SEEK_SET); numRead = fread(str, 6, 1, file); if (numRead < 1 || memcmp(str, "#?RGBE", 6)) { fclose(file); return false; } } fseek(file, 1, SEEK_CUR); // char cmd[2000]; i = 0; char c = 0, oldc; while (true) { oldc = c; c = fgetc(file); if (c == 0xa && oldc == 0xa) break; // cmd[i++] = c; } char reso[2000]; i = 0; while (true) { c = fgetc(file); reso[i++] = c; if (c == 0xa) break; } int w, h; if (!sscanf(reso, "-Y %d +X %d", &h, &w)) { fclose(file); return false; } _res.width = w; _res.height = h; int components = _rawRGBE ? 4 : 3; float *cols = new float[w * h * components]; _res.cols = cols; RGBE *scanline = new RGBE[w]; if (!scanline) { fclose(file); return false; } // convert image cols += (h - 1) * w * components; for (int y = h - 1; y >= 0; y--) { if (decrunch(scanline, w, file) == false) break; if (_rawRGBE) rawRGBEData(scanline, w, cols); else workOnRGBE(scanline, w, cols); cols -= w * components; } delete[] scanline; fclose(file); return true; }
int xmp_load_module(xmp_context opaque, char *path) { struct context_data *ctx = (struct context_data *)opaque; #ifndef LIBXMP_CORE_PLAYER struct module_data *m = &ctx->m; long size; char *temp_name; #endif HIO_HANDLE *h; struct stat st; int ret; D_(D_WARN "path = %s", path); /* if (stat(path, &st) < 0) return -XMP_ERROR_SYSTEM; */ #ifndef _MSC_VER if (S_ISDIR(st.st_mode)) { errno = EISDIR; return -XMP_ERROR_SYSTEM; } #endif if ((h = hio_open(path, "rb")) == NULL) return -XMP_ERROR_SYSTEM; #ifndef LIBXMP_CORE_PLAYER D_(D_INFO "decrunch"); if (decrunch(&h, path, &temp_name) < 0) goto err_depack; size = hio_size(h); if (size < 256) { /* get size after decrunch */ hio_close(h); unlink_temp_file(temp_name); return -XMP_ERROR_FORMAT; } #endif if (ctx->state > XMP_STATE_UNLOADED) xmp_release_module(opaque); #ifndef LIBXMP_CORE_PLAYER m->dirname = get_dirname(path); if (m->dirname == NULL) return -XMP_ERROR_SYSTEM; m->basename = get_basename(path); if (m->basename == NULL) return -XMP_ERROR_SYSTEM; m->filename = path; /* For ALM, SSMT, etc */ m->size = size; #endif ret = load_module(opaque, h); hio_close(h); #ifndef LIBXMP_CORE_PLAYER unlink_temp_file(temp_name); #endif return ret; #ifndef LIBXMP_CORE_PLAYER err_depack: hio_close(h); unlink_temp_file(temp_name); return -XMP_ERROR_DEPACK; #endif }
int xmp_test_module(char *path, struct xmp_test_info *info) { HIO_HANDLE *h; struct stat st; char buf[XMP_NAME_SIZE]; int i; int ret = -XMP_ERROR_FORMAT; #ifndef LIBXMP_CORE_PLAYER char *temp = NULL; #endif if (stat(path, &st) < 0) return -XMP_ERROR_SYSTEM; #ifndef _MSC_VER if (S_ISDIR(st.st_mode)) { errno = EISDIR; return -XMP_ERROR_SYSTEM; } #endif if ((h = hio_open(path, "rb")) == NULL) return -XMP_ERROR_SYSTEM; #ifndef LIBXMP_CORE_PLAYER if (decrunch(&h, path, &temp) < 0) { ret = -XMP_ERROR_DEPACK; goto err; } /* get size after decrunch */ if (hio_size(h) < 256) { /* set minimum valid module size */ ret = -XMP_ERROR_FORMAT; goto err; } #endif if (info != NULL) { *info->name = 0; /* reset name prior to testing */ *info->type = 0; /* reset type prior to testing */ } for (i = 0; format_loader[i] != NULL; i++) { hio_seek(h, 0, SEEK_SET); if (format_loader[i]->test(h, buf, 0) == 0) { int is_prowizard = 0; #ifndef LIBXMP_CORE_PLAYER if (strcmp(format_loader[i]->name, "prowizard") == 0) { hio_seek(h, 0, SEEK_SET); pw_test_format(h, buf, 0, info); is_prowizard = 1; } #endif fclose(h->handle.file); #ifndef LIBXMP_CORE_PLAYER unlink_temp_file(temp); #endif if (info != NULL && !is_prowizard) { strncpy(info->name, buf, XMP_NAME_SIZE); strncpy(info->type, format_loader[i]->name, XMP_NAME_SIZE); } return 0; } } #ifndef LIBXMP_CORE_PLAYER err: hio_close(h); unlink_temp_file(temp); #else hio_close(h); #endif return ret; }