/** * Parse the display segment packet. * * The display segment controls the updating of the display. * * @param avctx contains the current codec context * @param data pointer to the data pertaining the subtitle to display * @param buf pointer to the packet to process * @param buf_size size of packet to process * @todo TODO: Fix start time, relies on correct PTS, currently too late * * @todo TODO: Fix end time, normally cleared by a second display * @todo segment, which is currently ignored as it clears * @todo the subtitle too early. */ static int display_end_segment(AVCodecContext *avctx, void *data, const uint8_t *buf, int buf_size) { AVSubtitle *sub = data; PGSSubContext *ctx = avctx->priv_data; /* * The end display time is a timeout value and is only reached * if the next subtitle is later then timeout or subtitle has * not been cleared by a subsequent empty display command. */ memset(sub, 0, sizeof(*sub)); sub->pts = ctx->presentation.pts; // Blank if last object_number was 0. // Note that this may be wrong for more complex subtitles. if (!ctx->presentation.object_number) return 1; sub->start_display_time = 0; sub->end_display_time = 20000; sub->format = 0; sub->rects = av_mallocz(sizeof(*sub->rects)); sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); sub->num_rects = 1; if (ctx->presentation.composition_flag & 0x40) sub->rects[0]->flags |= AV_SUBTITLE_FLAG_FORCED; sub->rects[0]->x = ctx->presentation.x; sub->rects[0]->y = ctx->presentation.y; sub->rects[0]->w = ctx->picture.w; sub->rects[0]->h = ctx->picture.h; sub->rects[0]->type = SUBTITLE_BITMAP; /* Process bitmap */ sub->rects[0]->pict.linesize[0] = ctx->picture.w; if (ctx->picture.rle) { if (ctx->picture.rle_remaining_len) av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n", ctx->picture.rle_data_len, ctx->picture.rle_remaining_len); if(decode_rle(avctx, sub, ctx->picture.rle, ctx->picture.rle_data_len) < 0) return 0; } /* Allocate memory for colors */ sub->rects[0]->nb_colors = 256; sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); memcpy(sub->rects[0]->pict.data[1], ctx->clut, sub->rects[0]->nb_colors * sizeof(uint32_t)); return 1; }
static bool read_channel_pixels( FILE* fp, IplImage* channel, int c_width, int c_height, int c_depth, bool isMerged) { int i,j; uint16_t compression = read_2byte_BE(fp); int bytes_per_pixel = c_depth / 8; int bytes_per_row = c_width * bytes_per_pixel; int total_bytes = bytes_per_row * c_height; switch(compression){ case PSD_CM_NONE: for(j=0; j<c_height; j++){ uint8_t* dst = GetPixelAddress(channel, 0, j); for(i=0; i<c_width; i++){ (*dst) = read_1byte_BE(fp); dst++; } } break; case PSD_CM_RLE: { uint16_t* rle_pack_len = (uint16_t*) malloc(c_height * 2); for(i=0; i<c_height; i++){ rle_pack_len[i] = read_2byte_BE(fp); } for(i=0; i<c_height; i++){ uint8_t* src = (uint8_t*) malloc(rle_pack_len[i]); if(!fread(src, rle_pack_len[i], 1, fp)){ return false; } uint8_t* dst = GetPixelAddress(channel, 0, i); decode_rle((int8_t*)src, rle_pack_len[i], bytes_per_row, (int8_t*)dst); free(src); } } break; default: return false; break; } return true; }
/** * Parses the display segment packet. * * The display segment controls the updating of the display. * * @param avctx contains the current codec context * @param data pointer to the data pertaining the subtitle to display * @param buf pointer to the packet to process * @param buf_size size of packet to process * @todo TODO: Fix start time, relies on correct PTS, currently too late * * @todo TODO: Fix end time, normally cleared by a second display * @todo segment, which is currently ignored as it clears * @todo the subtitle too early. */ static int display_end_segment(AVCodecContext *avctx, void *data, const uint8_t *buf, int buf_size) { AVSubtitle *sub = data; PGSSubContext *ctx = avctx->priv_data; /* * The end display time is a timeout value and is only reached * if the next subtitle is later then timeout or subtitle has * not been cleared by a subsequent empty display command. */ memset(sub, 0, sizeof(*sub)); sub->start_display_time = 0; sub->end_display_time = 20000; sub->format = 0; sub->rects = av_mallocz(sizeof(*sub->rects)); sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); sub->num_rects = 1; sub->rects[0]->x = ctx->presentation.x; sub->rects[0]->y = ctx->presentation.y; sub->rects[0]->w = ctx->picture.w; sub->rects[0]->h = ctx->picture.h; sub->rects[0]->type = SUBTITLE_BITMAP; /* Process bitmap */ sub->rects[0]->pict.linesize[0] = ctx->picture.w; if (ctx->picture.rle) if(decode_rle(avctx, sub, ctx->picture.rle, ctx->picture.rle_data_len) < 0) return 0; /* Allocate memory for colors */ sub->rects[0]->nb_colors = 256; sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); memcpy(sub->rects[0]->pict.data[1], ctx->clut, sub->rects[0]->nb_colors * sizeof(uint32_t)); return 1; }
int main(int argc, char *argv[]) { char *program = argv[0]; if (argc != 2) invocation_error(program, "[file]"); char *iname = argv[1]; FILE *istream; if ((istream = fopen(iname, "rb")) == NULL) exit_error(errno, program, iname); char *oname = build_output_file_name(iname); FILE *ostream; if ((ostream = fopen(oname, "wb")) == NULL) { print_error(errno, program, oname); free(oname); if (fclose(istream) == EOF) exit_error(errno, program, iname); exit(EXIT_FAILURE); } /* * Process */ if (is_rle_file(oname)) encode_rle(istream, ostream); else decode_rle(istream, ostream); /* * Clean up */ free(oname); if (fclose(istream) == EOF) print_error(errno, program, iname); if (fclose(ostream) == EOF) exit_error(errno, program, oname); return 0; }
static void __init rb751_wlan_setup(void) { u8 *hardconfig = (u8 *) KSEG1ADDR(RB751_HARDCONFIG); struct ath9k_platform_data *wmac_data; int dec_size; wmac_data = ap9x_pci_get_wmac_data(0); if (!wmac_data) { pr_err("rb75x: unable to get address of wlan data\n"); return; } dec_size = decode_rle((char *) wmac_data->eeprom_data, sizeof(wmac_data->eeprom_data), hardconfig + RB751_CALDATA_OFFSET); if (dec_size != sizeof(wmac_data->eeprom_data)) { pr_err("rb75x: unable to decode wlan eeprom data\n"); return; } ap91_pci_init(NULL, hardconfig + RB751_MAC_ADDRESS_OFFSET); }
static int polly_test(FILE *f, char *t, const int start) { int i; uint8 *buf; if (read8(f) != 0xae) return -1; if ((buf = malloc(0x10000)) == NULL) return -1; decode_rle(buf, f, 0x10000); for (i = 0; i < 128; i++) { if (buf[ORD_OFS + i] != 0 && buf[ORD_OFS] < 0xe0) { free(buf); return -1; } } if (t) { memcpy(t, buf + ORD_OFS + 160, 16); t[16] = 0; for (i = 15; i >=0; i--) { if (t[i] == ' ') { t[i] = 0; } else { break; } } } free(buf); return 0; }
void packet_AF1F(char *buffer,int *offset,int *flag) { /* display Packet AF1F Rdial Data Packet (16 level) information flag[7] contains scale data: 1=refl 2=vel 0.5m/s 3=vel 1m/s 4=sw */ short num_radials=0; int i; /* j; */ short num_rle_halfwords=0; short range_bins; short start_angle,delta_angle; short istart_angle; short radial_found=FALSE; int start=0,end=0; short code=2; /* used for sending rle decoding instructions to the BSCAN module */ /* CVT 4.3 internal diagnostics */ /* enum{NOMOD,RLE,BSCAN}; defined in cvt.h */ /* char *truefalse[]={"FALSE","TRUE"}; */ /* char *format[]={"NONE","RLE","BSCAN"}; */ /* char *scale[]={"NOSCALE","REFL","VEL1","VEL2","SW"}; */ fprintf(stderr,"\n---------------- Decoding Packet AF1Fx -----------------\n"); fprintf(stderr,"Index of First Range Bin:\t\t\t%hd\n",read_half(buffer,offset)); range_bins=read_half(buffer,offset); fprintf(stderr,"Number of Range Bins:\t\t\t\t%hd\n",range_bins); fprintf(stderr,"I center of sweep:\t\t\t\t%hd\n",read_half(buffer,offset)); fprintf(stderr,"J center of sweep:\t\t\t\t%hd\n",read_half(buffer,offset)); fprintf(stderr,"Scale Factor:\t\t\t\t\t%hd\n",read_half(buffer,offset)); num_radials=read_half(buffer,offset); fprintf(stderr,"Number of Radials\t\t\t\t%hd\n",num_radials); fprintf(stderr,"\n"); /* test for format flag etc. */ if((flag[0]==RADIAL) && (flag[5]==RLE)) { fprintf(stderr,"Radials Left in Run-Length Encoded Format\n"); } else if(flag[0]==RADIAL) { fprintf(stderr,"Radials Unpacked to show all Data Values\n"); } if(flag[5]==BSCAN) { fprintf(stderr,"BSCAN Format Output Selected\n"); } /* CVT 4.3 internal diagnostics */ /* fprintf(stderr,"Diagnostic Information:\n"); */ /* start=flag[1]; */ /* fprintf(stderr,"Start Field:\t\t\t\t\t%hd\n",start); */ /* end=flag[2]; */ /* fprintf(stderr,"End Field:\t\t\t\t\t%hd\n",end); */ /* fprintf(stderr,"All Flag:\t\t\t\t\t%s\n",truefalse[flag[3]]); */ /* fprintf(stderr,"Degree Flag:\t\t\t\t\t%s\n",truefalse[flag[4]]); */ /* fprintf(stderr,"Output Format:\t\t\t\t\t%s\n",format[flag[5]]); */ /* fprintf(stderr,"Scale Flag:\t\t\t\t\t%s\n",scale[flag[7]]); */ /* fprintf(stderr,"\n"); */ start=flag[1]; end=flag[2]; /* CVT 4.4 */ if(flag[1]==0 && flag[2]==0) /* assume all radials desired */ flag[3] = TRUE; /* check for 'all' flag & reset start and end flags */ if(flag[3]==TRUE) { if(flag[4]==TRUE) { /* use degree values */ start=0; end=359; } else { /* use all values */ start=1; end=num_radials; } } /* quality control input values */ if(start>num_radials) { fprintf(stderr,"Range Error: The Radial Start Value of %d Exceeds the Max Number of Radials (%d)\n", start,num_radials); return; } if(end<0) { fprintf(stderr,"Range Error: The Radial End Value of %d is out of bounds\n",end); return; } if(flag[4]==TRUE && (start>359 || start<0)) { fprintf(stderr,"Range Error: The Radial Start Value of %d must be within 0-359 degrees\n", start); return; } if(flag[4]==TRUE && (end >359 || start<0)) { fprintf(stderr,"Range Error: The Radial End Value of %d must be within 0-359 degrees\n", end); return; } if(flag[5]==BSCAN) { /* output data in BSCAN format (bypass all further radial processing */ generate_BSCAN(num_radials,range_bins,code,buffer,offset,flag); return; } /* process for each radial */ for(i=1; i<=num_radials; i++) { /* read the radial header */ num_rle_halfwords=read_half(buffer,offset); /* a halfword is 2 bytes */ start_angle=read_half(buffer,offset); istart_angle=(short)(start_angle/10.0); delta_angle=read_half(buffer,offset); /*fprintf(stderr,"radial %d #rle halfwords %04hd start angle %04hd delta angle %04hd\n", i,num_rle_halfwords,start_angle,delta_angle);*/ if(flag[4]==FALSE) { /* process actual radial values */ if(end==0) { /* only one radial is requested */ if(start!=i) { advance_offset(buffer,offset,2*num_rle_halfwords); continue; } } /* end if end==0 */ if(end!=0) { /* more than one radial is requested */ /* fprintf(stderr,"radial %d start=%d end=%d\n",i,start,end);*/ if(start>end) { /* range from 358 to 2 degrees has start val > end */ if(i<start && i>end) { advance_offset(buffer,offset,2*num_rle_halfwords); continue; } } else { /* normal processing with start val < end val */ if(i<start || i>end) { advance_offset(buffer,offset,2*num_rle_halfwords); continue; } } /* end else */ } /* end if end!=0 */ } /* end if flag[4] FALSE*/ if(flag[4]==TRUE) { /* process degree values */ if(end==0) { /* only one radial is requested */ if(start!=istart_angle) { advance_offset(buffer,offset,2*num_rle_halfwords); continue; } } if(end!=0) { /* more than one radial is requested */ /* fprintf(stderr,"radial %d start=%d istart_angle=%d end=%d\n", i,start,istart_angle,end);*/ if(start>end) { /* range from 358 to 2 degrees has start val > end */ if(istart_angle<start && istart_angle>end) { advance_offset(buffer,offset,2*num_rle_halfwords); continue; } } else { /* normal processing with start val < end val */ if(istart_angle<start || istart_angle>end) { advance_offset(buffer,offset,2*num_rle_halfwords); continue; } } /* end else */ } /* end if end!=0 */ } /* end if flag[4] TRUE */ radial_found=TRUE; if(flag[5]==RLE) { /* output radial data in hexidecimal RLE encoded format */ print_rle("AF1F RLE Output",i,start_angle,delta_angle,buffer,offset, 2*num_rle_halfwords); } else { /* output radial data in decimal non-RLE encoded format */ decode_rle("AF1F Decimal Output",i,start_angle,delta_angle,buffer,offset, 2*num_rle_halfwords, range_bins, flag[7]); } } /* end of i loop */ if(radial_found==FALSE) { fprintf(stderr,"WARNING: No data was found for radial range start: %hd end: %hd\n", start,end); } }
static int polly_load(struct module_data *m, FILE *f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; uint8 *buf; int i, j, k; LOAD_INIT(); read8(f); /* skip 0xae */ /* * File is RLE-encoded, escape is 0xAE (Aleksi Eeben's initials). * Actual 0xAE is encoded as 0xAE 0x01 */ if ((buf = calloc(1, 0x10000)) == NULL) return -1; decode_rle(buf, f, 0x10000); for (i = 0; buf[ORD_OFS + i] != 0 && i < 128; i++) mod->xxo[i] = buf[ORD_OFS + i] - 0xe0; mod->len = i; memcpy(mod->name, buf + ORD_OFS + 160, 16); /* memcpy(m->author, buf + ORD_OFS + 176, 16); */ set_type(m, "Polly Tracker"); MODULE_INFO(); mod->spd = 0x03; mod->bpm = 0x7d * buf[ORD_OFS + 193] / 0x88; #if 0 for (i = 0; i < 1024; i++) { if ((i % 16) == 0) printf("\n"); printf("%02x ", buf[ORD_OFS + i]); } #endif mod->pat = 0; for (i = 0; i < mod->len; i++) { if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; mod->chn = 4; mod->trk = mod->pat * mod->chn; PATTERN_INIT(); D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { PATTERN_ALLOC(i); mod->xxp[i]->rows = 64; TRACK_ALLOC(i); for (j = 0; j < 64; j++) { for (k = 0; k < 4; k++) { uint8 x = buf[i * PAT_SIZE + j * 4 + k]; event = &EVENT(i, k, j); if (x == 0xf0) { event->fxt = FX_BREAK; event->fxp = 0; continue; } event->note = LSN(x); if (event->note) event->note += 48; event->ins = MSN(x); } } } mod->ins = mod->smp = 15; INSTRUMENT_INIT(); for (i = 0; i < 15; i++) { mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); mod->xxs[i].len = buf[ORD_OFS + 129 + i] < 0x10 ? 0 : 256 * buf[ORD_OFS + 145 + i]; mod->xxi[i].sub[0].fin = 0; mod->xxi[i].sub[0].vol = 0x40; mod->xxs[i].lps = 0; mod->xxs[i].lpe = 0; mod->xxs[i].flg = 0; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxi[i].nsm = !!(mod->xxs[i].len); mod->xxi[i].rls = 0xfff; D_(D_INFO "[%2X] %04x %04x %04x %c V%02x", i, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, ' ', mod->xxi[i].sub[0].vol); } /* Convert samples from 6 to 8 bits */ for (i = SMP_OFS; i < 0x10000; i++) buf[i] = buf[i] << 2; /* Read samples */ D_(D_INFO "Loading samples: %d", mod->ins); for (i = 0; i < mod->ins; i++) { if (mod->xxs[i].len == 0) continue; load_sample(NULL, SAMPLE_FLAG_NOLOAD | SAMPLE_FLAG_UNS, &mod->xxs[mod->xxi[i].sub[0].sid], (char*)buf + ORD_OFS + 256 + 256 * (buf[ORD_OFS + 129 + i] - 0x10)); } free(buf); /* make it mono */ for (i = 0; i < mod->chn; i++) mod->xxc[i].pan = 0x80; m->quirk |= QUIRK_MODRNG; return 0; }
/* * * Decode a frame * */ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { CamtasiaContext * const c = avctx->priv_data; unsigned char *encoded = (unsigned char *)buf; unsigned char *outptr; #ifdef CONFIG_ZLIB int zret; // Zlib return code #endif int len = buf_size; if(c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); c->pic.reference = 1; c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; if(avctx->get_buffer(avctx, &c->pic) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } outptr = c->pic.data[0]; // Output image pointer #ifdef CONFIG_ZLIB zret = inflateReset(&(c->zstream)); if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); return -1; } c->zstream.next_in = encoded; c->zstream.avail_in = len; c->zstream.next_out = c->decomp_buf; c->zstream.avail_out = c->decomp_size; zret = inflate(&(c->zstream), Z_FINISH); // Z_DATA_ERROR means empty picture if ((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) { av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); return -1; } if(zret != Z_DATA_ERROR) decode_rle(c, c->zstream.avail_out); /* make the palette available on the way out */ if (c->avctx->pix_fmt == PIX_FMT_PAL8) { memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE); if (c->avctx->palctrl->palette_changed) { c->pic.palette_has_changed = 1; c->avctx->palctrl->palette_changed = 0; } } #else av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); return -1; #endif *data_size = sizeof(AVFrame); *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return buf_size; }
/** * Parse the display segment packet. * * The display segment controls the updating of the display. * * @param avctx contains the current codec context * @param data pointer to the data pertaining the subtitle to display * @param buf pointer to the packet to process * @param buf_size size of packet to process * @todo TODO: Fix start time, relies on correct PTS, currently too late * * @todo TODO: Fix end time, normally cleared by a second display * @todo segment, which is currently ignored as it clears * @todo the subtitle too early. */ static int display_end_segment(AVCodecContext *avctx, void *data, const uint8_t *buf, int buf_size) { AVSubtitle *sub = data; PGSSubContext *ctx = avctx->priv_data; int64_t pts; uint16_t rect; /* * The end display time is a timeout value and is only reached * if the next subtitle is later than timeout or subtitle has * not been cleared by a subsequent empty display command. */ pts = ctx->pts != AV_NOPTS_VALUE ? ctx->pts : sub->pts; memset(sub, 0, sizeof(*sub)); sub->pts = pts; ctx->pts = AV_NOPTS_VALUE; // Blank if last object_count was 0. if (!ctx->presentation.object_count) return 1; sub->start_display_time = 0; sub->end_display_time = 20000; sub->format = 0; sub->num_rects = ctx->presentation.object_count; sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects); for (rect = 0; rect < sub->num_rects; ++rect) { uint16_t picture_id = ctx->presentation.objects[rect].picture_id; sub->rects[rect] = av_mallocz(sizeof(*sub->rects[rect])); sub->rects[rect]->x = ctx->presentation.objects[rect].x; sub->rects[rect]->y = ctx->presentation.objects[rect].y; sub->rects[rect]->w = ctx->pictures[picture_id].w; sub->rects[rect]->h = ctx->pictures[picture_id].h; sub->rects[rect]->type = SUBTITLE_BITMAP; /* Process bitmap */ sub->rects[rect]->pict.linesize[0] = ctx->pictures[picture_id].w; if (ctx->pictures[picture_id].rle) { if (ctx->pictures[picture_id].rle_remaining_len) av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n", ctx->pictures[picture_id].rle_data_len, ctx->pictures[picture_id].rle_remaining_len); if (decode_rle(avctx, sub, rect, ctx->pictures[picture_id].rle, ctx->pictures[picture_id].rle_data_len) < 0) return 0; } /* Allocate memory for colors */ sub->rects[rect]->nb_colors = 256; sub->rects[rect]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); /* Copy the forced flag */ sub->rects[rect]->forced = (ctx->presentation.objects[rect].composition & 0x40) != 0; if (!avctx->forced_subs_only || ctx->presentation.objects[rect].composition & 0x40) memcpy(sub->rects[rect]->pict.data[1], ctx->clut, sub->rects[rect]->nb_colors * sizeof(uint32_t)); } return 1; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { AVFrame * const p = data; GetByteContext gbc; int colors; int w, h, ret; int ver; bytestream2_init(&gbc, avpkt->data, avpkt->size); if ( bytestream2_get_bytes_left(&gbc) >= 552 && check_header(gbc.buffer + 512, bytestream2_get_bytes_left(&gbc) - 512) ) bytestream2_skip(&gbc, 512); ver = check_header(gbc.buffer, bytestream2_get_bytes_left(&gbc)); /* smallest PICT header */ if (bytestream2_get_bytes_left(&gbc) < 40) { av_log(avctx, AV_LOG_ERROR, "Frame is too small %d\n", bytestream2_get_bytes_left(&gbc)); return AVERROR_INVALIDDATA; } bytestream2_skip(&gbc, 6); h = bytestream2_get_be16(&gbc); w = bytestream2_get_be16(&gbc); ret = ff_set_dimensions(avctx, w, h); if (ret < 0) return ret; /* version 1 is identified by 0x1101 * it uses byte-aligned opcodes rather than word-aligned */ if (ver == 1) { avpriv_request_sample(avctx, "QuickDraw version 1"); return AVERROR_PATCHWELCOME; } else if (ver != 2) { avpriv_request_sample(avctx, "QuickDraw version unknown (%X)", bytestream2_get_be32(&gbc)); return AVERROR_PATCHWELCOME; } bytestream2_skip(&gbc, 4+26); while (bytestream2_get_bytes_left(&gbc) >= 4) { int bppcnt, bpp; int rowbytes, pack_type; int opcode = bytestream2_get_be16(&gbc); switch(opcode) { case PACKBITSRECT: case PACKBITSRGN: av_log(avctx, AV_LOG_DEBUG, "Parsing Packbit opcode\n"); bytestream2_skip(&gbc, 30); bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */ bpp = bytestream2_get_be16(&gbc); /* cmpSize */ av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp); if (bppcnt == 1 && bpp == 8) { avctx->pix_fmt = AV_PIX_FMT_PAL8; } else { av_log(avctx, AV_LOG_ERROR, "Invalid pixel format (bppcnt %d bpp %d) in Packbit\n", bppcnt, bpp); return AVERROR_INVALIDDATA; } /* jump to palette */ bytestream2_skip(&gbc, 18); colors = bytestream2_get_be16(&gbc); if (colors < 0 || colors > 256) { av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors); return AVERROR_INVALIDDATA; } if (bytestream2_get_bytes_left(&gbc) < (colors + 1) * 8) { av_log(avctx, AV_LOG_ERROR, "Palette is too small %d\n", bytestream2_get_bytes_left(&gbc)); return AVERROR_INVALIDDATA; } if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; parse_palette(avctx, &gbc, (uint32_t *)p->data[1], colors); p->palette_has_changed = 1; /* jump to image data */ bytestream2_skip(&gbc, 18); if (opcode == PACKBITSRGN) { bytestream2_skip(&gbc, 2 + 8); /* size + rect */ avpriv_report_missing_feature(avctx, "Packbit mask region"); } ret = decode_rle(avctx, p, &gbc, bppcnt); if (ret < 0) return ret; *got_frame = 1; break; case DIRECTBITSRECT: case DIRECTBITSRGN: av_log(avctx, AV_LOG_DEBUG, "Parsing Directbit opcode\n"); bytestream2_skip(&gbc, 4); rowbytes = bytestream2_get_be16(&gbc) & 0x3FFF; if (rowbytes <= 250) { avpriv_report_missing_feature(avctx, "Short rowbytes"); return AVERROR_PATCHWELCOME; } bytestream2_skip(&gbc, 10); pack_type = bytestream2_get_be16(&gbc); bytestream2_skip(&gbc, 16); bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */ bpp = bytestream2_get_be16(&gbc); /* cmpSize */ av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp); if (bppcnt == 3 && bpp == 8) { avctx->pix_fmt = AV_PIX_FMT_RGB24; } else if (bppcnt == 4 && bpp == 8) { avctx->pix_fmt = AV_PIX_FMT_ARGB; } else { av_log(avctx, AV_LOG_ERROR, "Invalid pixel format (bppcnt %d bpp %d) in Directbit\n", bppcnt, bpp); return AVERROR_INVALIDDATA; } /* set packing when default is selected */ if (pack_type == 0) pack_type = bppcnt; if (pack_type != 3 && pack_type != 4) { avpriv_request_sample(avctx, "Pack type %d", pack_type); return AVERROR_PATCHWELCOME; } if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } /* jump to data */ bytestream2_skip(&gbc, 30); if (opcode == DIRECTBITSRGN) { bytestream2_skip(&gbc, 2 + 8); /* size + rect */ avpriv_report_missing_feature(avctx, "DirectBit mask region"); } ret = decode_rle(avctx, p, &gbc, bppcnt); if (ret < 0) return ret; *got_frame = 1; break; default: av_log(avctx, AV_LOG_TRACE, "Unknown 0x%04X opcode\n", opcode); break; } /* exit the loop when a known pixel block has been found */ if (*got_frame) { int eop, trail; /* re-align to a word */ bytestream2_skip(&gbc, bytestream2_get_bytes_left(&gbc) % 2); eop = bytestream2_get_be16(&gbc); trail = bytestream2_get_bytes_left(&gbc); if (eop != EOP) av_log(avctx, AV_LOG_WARNING, "Missing end of picture opcode (found 0x%04X)\n", eop); if (trail) av_log(avctx, AV_LOG_WARNING, "Got %d trailing bytes\n", trail); break; } } if (*got_frame) { p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; return avpkt->size; } else { av_log(avctx, AV_LOG_ERROR, "Frame contained no usable data\n"); return AVERROR_INVALIDDATA; } }
static bool read_psd_merged_image( FILE* fp, ImgFile_Ptr pFile, PsdHeader* header) { int i,j,k; AddNewLayerHandle* handle = (AddNewLayerHandle*)pFile->CreateImgFileHandle(IFH_ADD_NEW_LAYER ); handle->Do( pFile ); ImgLayer_Ptr new_layer = handle->GetNewLayer().lock(); pFile->ReleaseImgFileHandle(handle); handle = NULL; pFile->SetSelectLayer( new_layer ); IplImage* channels[4]; for(i=0; i<4; i++){ channels[i] = cvCreateImage(cvSize(header->col, header->row), IPL_DEPTH_8U, 1); } int bytes_per_pixel = header->depth / 8; int bytes_per_row = header->col * bytes_per_pixel; int total_bytes = bytes_per_row * header->row; int extra_channels; switch(header->mode){ case PSD_COLOR_MODE_RGB: extra_channels = header->channels - 3; } uint16_t** rle_pack_len = (uint16_t**) malloc(sizeof(uint16_t*) * header->channels); memset(rle_pack_len, 0, sizeof(uint16_t*) * header->channels); uint16_t compression = read_2byte_BE(fp); switch(compression){ case PSD_CM_NONE: { for(i=0; i<header->channels; i++){ uint8_t* dst = GetPixelAddress(channels[i], 0, 0); if(!fread(dst, total_bytes, 1, fp)){ return false; } } } break; case PSD_CM_RLE: { for(i=0; i<header->channels; i++){ rle_pack_len[i] = (uint16_t*) malloc(sizeof(uint16_t) * header->row); for(j=0; j<header->row; j++){ rle_pack_len[i][j] = read_2byte_BE(fp); } } for(i=0; i<header->channels; i++){ for(j=0; j<header->row; j++){ uint8_t* src = (uint8_t*) malloc(rle_pack_len[i][j]); uint8_t* dst = GetPixelAddress(channels[i], 0, j); if(!fread(src, rle_pack_len[i][j], 1, fp)){ return false; } decode_rle((int8_t*)src, rle_pack_len[i][j], bytes_per_row, (int8_t*)dst); free(src); } } } break; } if(rle_pack_len){ for(i=0; i<header->channels; i++){ if(rle_pack_len[i]){ free(rle_pack_len[i]); } } free(rle_pack_len); } if(header->channels == 3){ //set alpha channel cvSet(channels[3], cvScalar(255)); } new_layer->Merge( 0, 0, header->col, header->row, channels[2], channels[1], channels[0], channels[3]); LPUPDATE_DATA pData = new_layer->CreateUpdateData(); pData->isAll = true; new_layer->PushUpdateData( pData ); // cvReleaseImage( &channels[0] ); cvReleaseImage( &channels[1] ); cvReleaseImage( &channels[2] ); cvReleaseImage( &channels[3] ); uint32_t now = ftell(fp); fseek(fp, 0, SEEK_END); uint32_t end = ftell(fp); return true; }