Mercurial > libavcodec.hg
comparison aasc.c @ 7885:f874e1d5cf07 libavcodec
Factorize out code used for MS RLE format decoding in different decoders.
author | kostya |
---|---|
date | Thu, 18 Sep 2008 05:20:54 +0000 |
parents | e943e1409077 |
children | 48dcf657f897 |
comparison
equal
deleted
inserted
replaced
7884:4077df298ba2 | 7885:f874e1d5cf07 |
---|---|
28 #include <stdlib.h> | 28 #include <stdlib.h> |
29 #include <string.h> | 29 #include <string.h> |
30 | 30 |
31 #include "avcodec.h" | 31 #include "avcodec.h" |
32 #include "dsputil.h" | 32 #include "dsputil.h" |
33 #include "msrledec.h" | |
33 | 34 |
34 typedef struct AascContext { | 35 typedef struct AascContext { |
35 AVCodecContext *avctx; | 36 AVCodecContext *avctx; |
36 AVFrame frame; | 37 AVFrame frame; |
37 } AascContext; | 38 } AascContext; |
59 static int aasc_decode_frame(AVCodecContext *avctx, | 60 static int aasc_decode_frame(AVCodecContext *avctx, |
60 void *data, int *data_size, | 61 void *data, int *data_size, |
61 const uint8_t *buf, int buf_size) | 62 const uint8_t *buf, int buf_size) |
62 { | 63 { |
63 AascContext *s = avctx->priv_data; | 64 AascContext *s = avctx->priv_data; |
64 int stream_ptr = 4; | |
65 unsigned char rle_code; | |
66 unsigned char stream_byte; | |
67 int pixel_ptr = 0; | |
68 int row_dec, row_ptr; | |
69 int frame_size; | |
70 int i; | |
71 | 65 |
72 s->frame.reference = 1; | 66 s->frame.reference = 1; |
73 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | 67 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; |
74 if (avctx->reget_buffer(avctx, &s->frame)) { | 68 if (avctx->reget_buffer(avctx, &s->frame)) { |
75 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); | 69 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); |
76 return -1; | 70 return -1; |
77 } | 71 } |
78 | 72 |
79 row_dec = s->frame.linesize[0]; | 73 ff_msrle_decode(avctx, &s->frame, 8, buf, buf_size); |
80 row_ptr = (s->avctx->height - 1) * row_dec; | |
81 frame_size = row_dec * s->avctx->height; | |
82 | |
83 while (row_ptr >= 0) { | |
84 FETCH_NEXT_STREAM_BYTE(); | |
85 rle_code = stream_byte; | |
86 if (rle_code == 0) { | |
87 /* fetch the next byte to see how to handle escape code */ | |
88 FETCH_NEXT_STREAM_BYTE(); | |
89 if (stream_byte == 0) { | |
90 /* line is done, goto the next one */ | |
91 row_ptr -= row_dec; | |
92 pixel_ptr = 0; | |
93 } else if (stream_byte == 1) { | |
94 /* decode is done */ | |
95 break; | |
96 } else if (stream_byte == 2) { | |
97 /* reposition frame decode coordinates */ | |
98 FETCH_NEXT_STREAM_BYTE(); | |
99 pixel_ptr += stream_byte; | |
100 FETCH_NEXT_STREAM_BYTE(); | |
101 row_ptr -= stream_byte * row_dec; | |
102 } else { | |
103 /* copy pixels from encoded stream */ | |
104 if ((pixel_ptr + stream_byte > avctx->width * 3) || | |
105 (row_ptr < 0)) { | |
106 av_log(s->avctx, AV_LOG_ERROR, " AASC: frame ptr just went out of bounds (copy1)\n"); | |
107 break; | |
108 } | |
109 | |
110 rle_code = stream_byte; | |
111 if (stream_ptr + rle_code > buf_size) { | |
112 av_log(s->avctx, AV_LOG_ERROR, " AASC: stream ptr just went out of bounds (copy2)\n"); | |
113 break; | |
114 } | |
115 | |
116 for (i = 0; i < rle_code; i++) { | |
117 FETCH_NEXT_STREAM_BYTE(); | |
118 s->frame.data[0][row_ptr + pixel_ptr] = stream_byte; | |
119 pixel_ptr++; | |
120 } | |
121 if (rle_code & 1) | |
122 stream_ptr++; | |
123 } | |
124 } else { | |
125 /* decode a run of data */ | |
126 if ((pixel_ptr + rle_code > avctx->width * 3) || | |
127 (row_ptr < 0)) { | |
128 av_log(s->avctx, AV_LOG_ERROR, " AASC: frame ptr just went out of bounds (run1)\n"); | |
129 break; | |
130 } | |
131 | |
132 FETCH_NEXT_STREAM_BYTE(); | |
133 | |
134 while(rle_code--) { | |
135 s->frame.data[0][row_ptr + pixel_ptr] = stream_byte; | |
136 pixel_ptr++; | |
137 } | |
138 } | |
139 } | |
140 | |
141 /* one last sanity check on the way out */ | |
142 if (stream_ptr < buf_size) | |
143 av_log(s->avctx, AV_LOG_ERROR, " AASC: ended frame decode with bytes left over (%d < %d)\n", | |
144 stream_ptr, buf_size); | |
145 | 74 |
146 *data_size = sizeof(AVFrame); | 75 *data_size = sizeof(AVFrame); |
147 *(AVFrame*)data = s->frame; | 76 *(AVFrame*)data = s->frame; |
148 | 77 |
149 /* report that the buffer was completely consumed */ | 78 /* report that the buffer was completely consumed */ |