You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	cllc: Implement ARGB support
Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
This commit is contained in:
		| @@ -74,6 +74,80 @@ static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) | |||||||
|                               codes, 2, 2, symbols, 1, 1, 0); |                               codes, 2, 2, symbols, 1, 1, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Unlike the RGB24 read/restore, which reads in a component at a time, | ||||||
|  |  * ARGB read/restore reads in ARGB quads. | ||||||
|  |  */ | ||||||
|  | static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, | ||||||
|  |                           VLC *vlc, uint8_t *outbuf) | ||||||
|  | { | ||||||
|  |     uint8_t *dst; | ||||||
|  |     int pred[4]; | ||||||
|  |     int code; | ||||||
|  |     int i; | ||||||
|  |  | ||||||
|  |     OPEN_READER(bits, gb); | ||||||
|  |  | ||||||
|  |     dst     = outbuf; | ||||||
|  |     pred[0] = top_left[0]; | ||||||
|  |     pred[1] = top_left[1]; | ||||||
|  |     pred[2] = top_left[2]; | ||||||
|  |     pred[3] = top_left[3]; | ||||||
|  |  | ||||||
|  |     for (i = 0; i < ctx->avctx->width; i++) { | ||||||
|  |         /* Always get the alpha component */ | ||||||
|  |         UPDATE_CACHE(bits, gb); | ||||||
|  |         GET_VLC(code, bits, gb, vlc[0].table, 7, 2); | ||||||
|  |  | ||||||
|  |         pred[0] += code; | ||||||
|  |         dst[0]   = pred[0]; | ||||||
|  |  | ||||||
|  |         /* Skip the components if they are  entirely transparent */ | ||||||
|  |         if (dst[0]) { | ||||||
|  |             /* Red */ | ||||||
|  |             UPDATE_CACHE(bits, gb); | ||||||
|  |             GET_VLC(code, bits, gb, vlc[1].table, 7, 2); | ||||||
|  |  | ||||||
|  |             pred[1] += code; | ||||||
|  |             dst[1]   = pred[1]; | ||||||
|  |  | ||||||
|  |             /* Green */ | ||||||
|  |             UPDATE_CACHE(bits, gb); | ||||||
|  |             GET_VLC(code, bits, gb, vlc[2].table, 7, 2); | ||||||
|  |  | ||||||
|  |             pred[2] += code; | ||||||
|  |             dst[2]   = pred[2]; | ||||||
|  |  | ||||||
|  |             /* Blue */ | ||||||
|  |             UPDATE_CACHE(bits, gb); | ||||||
|  |             GET_VLC(code, bits, gb, vlc[3].table, 7, 2); | ||||||
|  |  | ||||||
|  |             pred[3] += code; | ||||||
|  |             dst[3]   = pred[3]; | ||||||
|  |         } else { | ||||||
|  |             dst[1] = 0; | ||||||
|  |             dst[2] = 0; | ||||||
|  |             dst[3] = 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         dst += 4; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     CLOSE_READER(bits, gb); | ||||||
|  |  | ||||||
|  |     dst         -= 4 * ctx->avctx->width; | ||||||
|  |     top_left[0]  = dst[0]; | ||||||
|  |  | ||||||
|  |     /* Only stash components if they are not transparent */ | ||||||
|  |     if (top_left[0]) { | ||||||
|  |         top_left[1] = dst[1]; | ||||||
|  |         top_left[2] = dst[2]; | ||||||
|  |         top_left[3] = dst[3]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, | static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, | ||||||
|                                      int *top_left, VLC *vlc, uint8_t *outbuf) |                                      int *top_left, VLC *vlc, uint8_t *outbuf) | ||||||
| { | { | ||||||
| @@ -104,6 +178,50 @@ static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) | ||||||
|  | { | ||||||
|  |     AVCodecContext *avctx = ctx->avctx; | ||||||
|  |     uint8_t *dst; | ||||||
|  |     int pred[4]; | ||||||
|  |     int ret; | ||||||
|  |     int i, j; | ||||||
|  |     VLC vlc[4]; | ||||||
|  |  | ||||||
|  |     pred[0] = 0; | ||||||
|  |     pred[1] = 0x80; | ||||||
|  |     pred[2] = 0x80; | ||||||
|  |     pred[3] = 0x80; | ||||||
|  |  | ||||||
|  |     dst = pic->data[0]; | ||||||
|  |  | ||||||
|  |     skip_bits(gb, 16); | ||||||
|  |  | ||||||
|  |     /* Read in code table for each plane */ | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         ret = read_code_table(ctx, gb, &vlc[i]); | ||||||
|  |         if (ret < 0) { | ||||||
|  |             for (j = 0; j <= i; j++) | ||||||
|  |                 ff_free_vlc(&vlc[j]); | ||||||
|  |  | ||||||
|  |             av_log(ctx->avctx, AV_LOG_ERROR, | ||||||
|  |                    "Could not read code table %d.\n", i); | ||||||
|  |             return ret; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* Read in and restore every line */ | ||||||
|  |     for (i = 0; i < avctx->height; i++) { | ||||||
|  |         read_argb_line(ctx, gb, pred, vlc, dst); | ||||||
|  |  | ||||||
|  |         dst += pic->linesize[0]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (i = 0; i < 4; i++) | ||||||
|  |         ff_free_vlc(&vlc[i]); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) | static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) | ||||||
| { | { | ||||||
|     AVCodecContext *avctx = ctx->avctx; |     AVCodecContext *avctx = ctx->avctx; | ||||||
| @@ -224,6 +342,21 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, | |||||||
|         if (ret < 0) |         if (ret < 0) | ||||||
|             return ret; |             return ret; | ||||||
|  |  | ||||||
|  |         break; | ||||||
|  |     case 3: | ||||||
|  |         avctx->pix_fmt             = PIX_FMT_ARGB; | ||||||
|  |         avctx->bits_per_raw_sample = 8; | ||||||
|  |  | ||||||
|  |         ret = avctx->get_buffer(avctx, pic); | ||||||
|  |         if (ret < 0) { | ||||||
|  |             av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); | ||||||
|  |             return ret; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         ret = decode_argb_frame(ctx, &gb, pic); | ||||||
|  |         if (ret < 0) | ||||||
|  |             return ret; | ||||||
|  |  | ||||||
|         break; |         break; | ||||||
|     default: |     default: | ||||||
|         av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type); |         av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user