avcodec/iff: add support for ANBR files
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
		
							parent
							
								
									e34e7a575e
								
							
						
					
					
						commit
						a5c5ae5ed8
					
				| @ -53,6 +53,7 @@ typedef struct IffContext { | ||||
|     unsigned  compression;  ///< delta compression method used
 | ||||
|     unsigned  is_short;     ///< short compression method used
 | ||||
|     unsigned  is_interlaced;///< video is interlaced
 | ||||
|     unsigned  is_brush;     ///< video is in ANBR format
 | ||||
|     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
 | ||||
|     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
 | ||||
|     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
 | ||||
| @ -230,6 +231,7 @@ static int extract_header(AVCodecContext *const avctx, | ||||
|                 bytestream2_skip(gb, 19); | ||||
|                 extra = bytestream2_get_be32(gb); | ||||
|                 s->is_short = !(extra & 1); | ||||
|                 s->is_brush = extra == 2; | ||||
|                 s->is_interlaced = !!(extra & 0x40); | ||||
|                 data_size -= 24; | ||||
|                 bytestream2_skip(gb, data_size + (data_size & 1)); | ||||
| @ -763,7 +765,7 @@ static void decode_short_horizontal_delta(uint8_t *dst, | ||||
| 
 | ||||
| static void decode_byte_vertical_delta(uint8_t *dst, | ||||
|                                        const uint8_t *buf, const uint8_t *buf_end, | ||||
|                                        int w, int bpp, int dst_size) | ||||
|                                        int w, int xor, int bpp, int dst_size) | ||||
| { | ||||
|     int ncolumns = ((w + 15) / 16) * 2; | ||||
|     int dstpitch = ncolumns * bpp; | ||||
| @ -798,7 +800,11 @@ static void decode_byte_vertical_delta(uint8_t *dst, | ||||
| 
 | ||||
|                     while (opcode) { | ||||
|                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET); | ||||
|                         bytestream2_put_byte(&pb, x); | ||||
|                         if (xor && ofsdst < dst_size) { | ||||
|                             bytestream2_put_byte(&pb, dst[ofsdst] ^ x); | ||||
|                         } else { | ||||
|                             bytestream2_put_byte(&pb, x); | ||||
|                         } | ||||
|                         ofsdst += dstpitch; | ||||
|                         opcode--; | ||||
|                     } | ||||
| @ -809,7 +815,11 @@ static void decode_byte_vertical_delta(uint8_t *dst, | ||||
| 
 | ||||
|                     while (opcode) { | ||||
|                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET); | ||||
|                         bytestream2_put_byte(&pb, bytestream2_get_byte(&gb)); | ||||
|                         if (xor && ofsdst < dst_size) { | ||||
|                             bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb)); | ||||
|                         } else { | ||||
|                             bytestream2_put_byte(&pb, bytestream2_get_byte(&gb)); | ||||
|                         } | ||||
|                         ofsdst += dstpitch; | ||||
|                         opcode--; | ||||
|                     } | ||||
| @ -1627,7 +1637,7 @@ static int decode_frame(AVCodecContext *avctx, | ||||
|         break; | ||||
|     case 0x500: | ||||
|     case 0x501: | ||||
|         decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size); | ||||
|         decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size); | ||||
|         break; | ||||
|     case 0x700: | ||||
|     case 0x701: | ||||
| @ -1719,8 +1729,10 @@ static int decode_frame(AVCodecContext *avctx, | ||||
|             return unsupported(avctx); | ||||
|         } | ||||
| 
 | ||||
|         FFSWAP(uint8_t *, s->video[0], s->video[1]); | ||||
|         FFSWAP(uint32_t *, s->pal[0], s->pal[1]); | ||||
|         if (!s->is_brush) { | ||||
|             FFSWAP(uint8_t *, s->video[0], s->video[1]); | ||||
|             FFSWAP(uint32_t *, s->pal[0], s->pal[1]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (avpkt->flags & AV_PKT_FLAG_KEY) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user