int swf_tag_get_bitmap_size(swf_tag_t *tag, int *width, int *height) { int ret = 0; if (tag == NULL) { fprintf(stderr, "swf_tag_get_bitmap_size: tag == NULL\n"); return 1; } if ((width == NULL ) || (height == NULL)) { fprintf(stderr, "swf_tag_get_bitmap_size: width == NULL or height == NULL\n"); return 1; } if (isBitsJPEGTag(tag->code)) { swf_tag_jpeg_detail_t *swf_tag_jpeg; if (swf_tag_create_input_detail(tag, NULL) == NULL) { fprintf(stderr, "swf_tag_get_bitmap_size: swf_tag_create_input_detail failed\n"); return 1; } swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail; ret = jpeg_size(swf_tag_jpeg->jpeg_data, swf_tag_jpeg->jpeg_data_len, width, height); } else if (isBitsLosslessTag(tag->code)) { if (tag->detail) { swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) tag->detail; *width = swf_tag_lossless->width; *height = swf_tag_lossless->height; } else { *width = GetUShortLE((tag->data + 3)); *height = GetUShortLE((tag->data + 5)); } } else { // no Bitmap Tag return 1; } return ret; }
int main(int argc, const char * const argv[]) { int fd, fdout; size_t read_size, block_size; unsigned int i, begin_index; unsigned char *start, *end, *addr; size_t size; int page_size; off_t offset; const char *file_format; const char *dir_format; int c; read_size = 128 * 1024 * 1024; block_size = 512; begin_index = 0; file_format = "image%05d.jpg"; dir_format = NULL; while ((c = getopt(argc, (char * const *) argv, "b:d:f:hi:m:qr:s:vV")) != -1) { switch (c) { case 'b': block_size = atol_suffix(optarg); break; case 'd': dir_format = optarg; break; case 'f': file_format = optarg; break; case 'i': begin_index = atoi(optarg); break; case 'm': max_size = atol_suffix(optarg); break; case 'q': quiet = 1; break; case 'r': read_size = atol_suffix(optarg); break; case 's': ignore_size = atol_suffix(optarg) - 1; break; case 'v': verbose = 1; break; case 'V': display_version_and_exit("recoverjpeg"); default: usage(c == 'h'); } } argc -= optind; argv += optind; if (argc != 1) { usage(0); } fd = open(argv[0], O_RDONLY); if (fd < 0) { fprintf(stderr, "recoverjpeg: unable to open %s for reading (%s)\n", argv[argc - 1], strerror(errno)); exit(1); } page_size = getpagesize(); if (read_size % page_size || read_size < max_size) { if (read_size < max_size) { read_size = max_size; } read_size = (read_size + page_size - 1) / page_size * page_size; if (!quiet) { fprintf(stderr, "Adjusted read size to %ld bytes\n", (long) read_size); } } start = end = (unsigned char *) malloc(read_size); if (start == 0) { fprintf(stderr, "recoverjpeg: cannot allocate necessary memory (%s)\n", strerror(errno)); exit(1); } for (i = 0, offset = 0, addr = NULL; addr < end;) { if (progressbar()) { display_progressbar(offset, i); } if (addr == NULL || (size_t) (start + read_size - addr) < max_size) { off_t base_offset; long n; base_offset = offset / page_size * page_size; lseek(fd, base_offset, SEEK_SET); n = read(fd, start, read_size); if (n < 0) { fprintf(stderr, "recoverjpeg: unable to read data (%s)\n", strerror(errno)); exit(1); } end = start + n; addr = start + (offset - base_offset); } size = jpeg_size(addr); if (size > ignore_size) { size_t n; const char *buffer = file_name(dir_format, file_format, begin_index + i); i++; if (verbose) { printf("%s %ld bytes\n", buffer, (long) size); } fdout = open(buffer, O_WRONLY | O_CREAT, 0666); if (fdout < 0) { fprintf(stderr, "Unable to open %s for writing\n", buffer); exit(1); } if ((size_t) write(fdout, addr, size) != size) { fprintf(stderr, "Unable to write %ld bytes to %s\n", (long) size, buffer); exit(1); } close(fdout); n = ((size + block_size - 1) / block_size) * block_size; addr += n; offset += n; } else { addr += block_size; offset += block_size; } } if (progressbar()) { cleanup_progressbar(); } if (!quiet) { printf("Restored %d picture%s\n", i, i > 1 ? "s" : ""); } /* Free allocated memory to keep valgrind happy */ free(start); exit(0); }