| #if defined(_MSC_VER) && (_MSC_VER >= 1400) |
| #define _CRT_SECURE_NO_DEPRECATE 1 |
| #endif |
| |
| #include "zlib.h" |
| |
| #include "psdutils.h" |
| |
| void readrow(FILE *psd, TPSDChannelInfo *chan, |
| psdPixel row, |
| unsigned char *inbuffer, |
| unsigned char * |
| tmpbuffer) |
| { |
| psdPixel n = 0, rlebytes; |
| psdByte pos; |
| |
| int seekres = 0; |
| |
| switch (chan->comptype) { |
| case RAWDATA: |
| pos = chan->filepos + chan->rowbytes * row; |
| seekres = fseek(psd, pos, SEEK_SET); |
| if (seekres != -1) n = (psdPixel)fread(inbuffer, 1, chan->rowbytes, psd); |
| break; |
| case RLECOMP: |
| pos = chan->rowpos[row]; |
| seekres = fseek(psd, pos, SEEK_SET); |
| if (seekres != -1) { |
| rlebytes = |
| (psdPixel)fread(tmpbuffer, 1, chan->rowpos[row + 1] - pos, psd); |
| n = unpackrow(inbuffer, tmpbuffer, chan->rowbytes, rlebytes); |
| } |
| break; |
| case ZIPWITHPREDICTION: |
| case ZIPWITHOUTPREDICTION: |
| memcpy(inbuffer, chan->unzipdata + chan->rowbytes * row, chan->rowbytes); |
| return; |
| } |
| |
| |
| |
| |
| |
| |
| if (n < chan->rowbytes) { |
| |
| |
| memset(inbuffer + n, 0, chan->rowbytes - n); |
| } |
| } |
| |
| int unpackrow(unsigned char *out, unsigned char *in, psdPixel outlen, |
| psdPixel inlen) { |
| psdPixel i, len; |
| int val; |
| |
| for (i = 0; inlen > 1 && i < outlen;) { |
| len = *in++; |
| --inlen; |
| |
| if (len == 128) |
| ; |
| else { |
| if (len > 128) { |
| len = 1 + 256 - len; |
| |
| val = *in++; |
| --inlen; |
| |
| if ((i + len) <= outlen) |
| memset(out, val, len); |
| else { |
| memset(out, val, outlen - i); |
| len = 0; |
| } |
| } else { |
| ++len; |
| if ((i + len) <= outlen) { |
| if (len > inlen) break; |
| memcpy(out, in, len); |
| in += len; |
| inlen -= len; |
| } else { |
| memcpy(out, in, outlen - i); |
| len = 0; |
| } |
| } |
| out += len; |
| i += len; |
| } |
| } |
| if (i < outlen) { |
| |
| } |
| return i; |
| } |
| |
| void skipBlock(FILE *f) { |
| psdByte n = read4Bytes(f); |
| if (n) { |
| fseek(f, n, SEEK_CUR); |
| } else { |
| } |
| } |
| |
| |
| |
| unsigned read2UBytes(FILE *f) { |
| unsigned n = fgetc(f) << 8; |
| return n |= fgetc(f); |
| } |
| |
| |
| int read2Bytes(FILE *f) { |
| unsigned n = fgetc(f) << 8; |
| n |= fgetc(f); |
| return n < 0x8000 ? n : n - 0x10000; |
| } |
| |
| |
| |
| long read4Bytes(FILE *f) { |
| long n = fgetc(f) << 24; |
| n |= fgetc(f) << 16; |
| n |= fgetc(f) << 8; |
| return n | fgetc(f); |
| } |
| |
| void *mymalloc(long n) { |
| void *p = malloc(n); |
| if (p) |
| return p; |
| else { |
| |
| } |
| return NULL; |
| } |
| |
| void *mycalloc(long n, int size) { |
| void *p = calloc(n, size); |
| if (p) |
| return p; |
| else { |
| |
| } |
| return NULL; |
| } |
| |
| |
| |
| |
| int psdUnzipWithoutPrediction(unsigned char *src_buf, int src_len, |
| unsigned char *dst_buf, int dst_len) { |
| z_stream stream; |
| int state; |
| |
| memset(&stream, 0, sizeof(z_stream)); |
| stream.data_type = Z_BINARY; |
| |
| stream.next_in = (Bytef *)src_buf; |
| stream.avail_in = src_len; |
| stream.next_out = (Bytef *)dst_buf; |
| stream.avail_out = dst_len; |
| |
| if (inflateInit(&stream) != Z_OK) return 0; |
| |
| do { |
| state = inflate(&stream, Z_PARTIAL_FLUSH); |
| if (state == Z_STREAM_END) break; |
| if (state == Z_DATA_ERROR || state != Z_OK) break; |
| } while (stream.avail_out > 0); |
| |
| if (state != Z_STREAM_END && state != Z_OK) return 0; |
| |
| return 1; |
| } |
| |
| |
| |
| int psdUnzipWithPrediction(unsigned char *src_buf, int src_len, |
| unsigned char *dst_buf, int dst_len, int row_size, |
| int color_depth) { |
| int status; |
| int len; |
| unsigned char *buf; |
| |
| status = psdUnzipWithoutPrediction(src_buf, src_len, dst_buf, dst_len); |
| if (!status) return status; |
| |
| buf = dst_buf; |
| do { |
| len = row_size; |
| if (color_depth == 16) { |
| while (--len) { |
| buf[2] += buf[0] + ((buf[1] + buf[3]) >> 8); |
| buf[3] += buf[1]; |
| buf += 2; |
| } |
| buf += 2; |
| dst_len -= row_size * 2; |
| } else { |
| while (--len) { |
| *(buf + 1) += *buf; |
| buf++; |
| } |
| buf++; |
| dst_len -= row_size; |
| } |
| } while (dst_len > 0); |
| |
| return 1; |
| } |