ipaPNG.zip

  • kuty77
    了解作者
  • C++
    开发工具
  • 10KB
    文件大小
  • zip
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 1
    下载次数
  • 2014-12-28 18:15
    上传日期
ipaPNG 解开IPA PNG图片 希望对你有帮助
ipaPNG.zip
  • ipaPNG
  • .svn
  • props
  • text-base
  • Makefile.svn-base
    331B
  • fixpng.c.svn-base
    6KB
  • flipchannels.c.svn-base
    4.4KB
  • tmp
  • props
  • text-base
  • prop-base
  • prop-base
  • entries
    604B
  • fixpng.c
    6KB
  • Makefile
    331B
  • flipchannels.c
    4.4KB
内容介绍
/* * fixpng.c * * Copyright 2007 MHW. Read the GPL v2.0 for legal details. * http://www.gnu.org/licenses/gpl-2.0.txt * * * This tool will convert iPhone PNGs from its weird, non-compatible format to * A format any PNG-compatible application will read. It will not flip the R * and B channels. * * In summary, this tool takes an input png uncompresses the IDAT chunk, recompresses * it in a PNG-compatible way and then writes everything except the, so far, * useless CgBI chunk to the output. * * It's a relatively quick hack, and it will break if the IDAT in either form * (compressed or uncompressed) is larger than 1MB, and if there are more than 20 * chunks before the IDAT(s). In that case, poke at MAX_CHUNKS and BUFSIZE. * * Usage therefore: fixpng <input.png> <output.png> */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <arpa/inet.h rel='nofollow' onclick='return false;'> #include <errno.h> #include <zlib.h> #define MAX_CHUNKS 20 #define BUFSIZE 1048576 // 1MB buffer size typedef unsigned int uint32; typedef struct png_chunk_t { uint32 length; unsigned char *name; unsigned char *data; uint32 crc; } png_chunk; png_chunk **chunks; unsigned char pngheader[8] = {137, 80, 78, 71, 13, 10, 26, 10}; unsigned char datachunk[4] = {0x49, 0x44, 0x41, 0x54}; // IDAT unsigned char endchunk[4] = {0x49, 0x45, 0x4e, 0x44}; // IEND unsigned char cgbichunk[4] = {0x43, 0x67, 0x42, 0x49}; // CgBI void die(char *why); int check_png_header(unsigned char *); void read_chunks(unsigned char *); void process_chunks(void); void write_png(char *); unsigned long mycrc(unsigned char *, unsigned char *, int); int main(int argc, char **argv){ int fd; unsigned char *buf; struct stat s; if(argc!=3) { printf("Usage: %s <input> <output>\n\n",argv[0]); exit(1); } fd = open(argv[1], O_RDONLY, 0); if (fstat(fd, &s) < 0) { die("Couldn't stat file\n"); } buf = (unsigned char *)malloc(s.st_size); if (read(fd, buf, s.st_size) != s.st_size) { die("Couldn't read file\n"); } if (!check_png_header(buf)){ die("This is not a PNG file. I require a PNG file!\n"); } chunks = malloc(sizeof(png_chunk *) * MAX_CHUNKS); read_chunks(buf); process_chunks(); write_png(argv[2]); } int check_png_header(unsigned char *buf){ return (!(int) memcmp(buf, pngheader, 8)); } void read_chunks(unsigned char* buf){ int i = 0; buf += 8; do { png_chunk *chunk; chunk = (png_chunk *)malloc(sizeof(png_chunk)); memcpy(&chunk->length, buf, 4); chunk->length = ntohl(chunk->length); chunk->data = (unsigned char *)malloc(chunk->length); chunk->name = (unsigned char *)malloc(4); buf += 4; memcpy(chunk->name, buf, 4); buf += 4; chunk->data = (unsigned char *)malloc(chunk->length); memcpy(chunk->data, buf, chunk->length); buf += chunk->length; memcpy(&chunk->crc, buf, 4); chunk->crc = ntohl(chunk->crc); buf += 4; printf("Found chunk: %c%c%c%c\n", chunk->name[0], chunk->name[1], chunk->name[2], chunk->name[3]); printf("Length: %d, CRC32: %08x\n", chunk->length, chunk->crc); *(chunks+i) = chunk; if (!memcmp(chunk->name, endchunk, 4)){ // End of img. break; } } while (i++ < MAX_CHUNKS); } void process_chunks(){ int i; unsigned char* outbuf; // Poke at any IDAT chunks and de/recompress them for (i = 0; i < MAX_CHUNKS; i++){ png_chunk *chunk; int ret; chunk = *(chunks+i); z_stream infstrm, defstrm; if (!memcmp(chunk->name, datachunk, 4)){ unsigned char *inflatedbuf; unsigned char *deflatedbuf; inflatedbuf = (unsigned char *)malloc(BUFSIZE); printf("processing IDAT chunk %d\n", i); infstrm.zalloc = Z_NULL; infstrm.zfree = Z_NULL; infstrm.opaque = Z_NULL; infstrm.avail_in = chunk->length; infstrm.next_in = chunk->data; infstrm.next_out = inflatedbuf; infstrm.avail_out = BUFSIZE; // Inflate using raw inflation if (inflateInit2(&infstrm,-8) != Z_OK){ die("ZLib error"); } ret = inflate(&infstrm, Z_NO_FLUSH); switch (ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; /* and fall through */ case Z_DATA_ERROR: case Z_MEM_ERROR: printf("ZLib error! %d\n", ret); inflateEnd(&infstrm); } inflateEnd(&infstrm); // Now deflate again, the regular, PNG-compatible, way deflatedbuf = (unsigned char *)malloc(BUFSIZE); defstrm.zalloc = Z_NULL; defstrm.zfree = Z_NULL; defstrm.opaque = Z_NULL; defstrm.avail_in = infstrm.total_out; defstrm.next_in = inflatedbuf; defstrm.next_out = deflatedbuf; defstrm.avail_out = BUFSIZE; deflateInit(&defstrm, Z_DEFAULT_COMPRESSION); deflate(&defstrm, Z_FINISH); chunk->data = deflatedbuf; chunk->length = defstrm.total_out; chunk->crc = mycrc(chunk->name, chunk->data, chunk->length); printf("New length: %d, new CRC: %08x\n", chunk->length, chunk->crc); } else if (!memcmp(chunk->name, endchunk, 4)){ break; } } } void write_png(char *filename){ int fd, i = 0; fd = open(filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); write(fd, pngheader, 8); for (i = 0; i < MAX_CHUNKS; i++){ png_chunk *chunk; int tmp; chunk = *(chunks+i); tmp = htonl(chunk->length); chunk->crc = htonl(chunk->crc); if (memcmp(chunk->name, cgbichunk, 4)){ // Anything but a CgBI int ret; ret = write(fd, &tmp, 4); ret = write(fd, chunk->name, 4); if (chunk->length > 0){ printf("About to write data to fd length %d\n", chunk->length); ret = write(fd, chunk->data, chunk->length); if (!ret){ printf("%c%c%c%c size %d\n", chunk->name[0], chunk->name[1], chunk->name[2], chunk->name[3], chunk->length); perror("write"); } } ret = write(fd, &chunk->crc, 4); } if (!memcmp(chunk->name, endchunk, 4)){ break; } } close(fd); } void die(char *why){ printf(why); exit(1); } unsigned long mycrc(unsigned char *name, unsigned char *buf, int len) { uint32 crc; crc = crc32(0, name, 4); return crc32(crc, buf, len); }
评论
    相关推荐