00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include "avcodec.h"
00032 #include "bytestream.h"
00033
00034 #include "ulti_cb.h"
00035
00036 typedef struct UltimotionDecodeContext {
00037 AVCodecContext *avctx;
00038 int width, height, blocks;
00039 AVFrame frame;
00040 const uint8_t *ulti_codebook;
00041 } UltimotionDecodeContext;
00042
00043 #define CHECK_OVERREAD_SIZE(size) \
00044 do { \
00045 if (buf_end - buf < (size)) { \
00046 av_log(avctx, AV_LOG_ERROR, "Insufficient data\n"); \
00047 return AVERROR_INVALIDDATA; \
00048 } \
00049 } while(0)
00050
00051 static av_cold int ulti_decode_init(AVCodecContext *avctx)
00052 {
00053 UltimotionDecodeContext *s = avctx->priv_data;
00054
00055 s->avctx = avctx;
00056 s->width = avctx->width;
00057 s->height = avctx->height;
00058 s->blocks = (s->width / 8) * (s->height / 8);
00059 avctx->pix_fmt = PIX_FMT_YUV410P;
00060 avcodec_get_frame_defaults(&s->frame);
00061 avctx->coded_frame = (AVFrame*) &s->frame;
00062 s->ulti_codebook = ulti_codebook;
00063
00064 return 0;
00065 }
00066
00067 static av_cold int ulti_decode_end(AVCodecContext *avctx){
00068 UltimotionDecodeContext *s = avctx->priv_data;
00069 AVFrame *pic = &s->frame;
00070
00071 if (pic->data[0])
00072 avctx->release_buffer(avctx, pic);
00073
00074 return 0;
00075 }
00076
00077 static const int block_coords[8] =
00078 { 0, 0, 0, 4, 4, 4, 4, 0};
00079
00080 static const int angle_by_index[4] = { 0, 2, 6, 12};
00081
00082
00083 static const uint8_t ulti_lumas[64] =
00084 { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,
00085 0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,
00086 0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,
00087 0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,
00088 0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,
00089 0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,
00090 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,
00091 0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};
00092
00093 static const uint8_t ulti_chromas[16] =
00094 { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,
00095 0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};
00096
00097
00098
00099 static void ulti_convert_yuv(AVFrame *frame, int x, int y,
00100 uint8_t *luma,int chroma)
00101 {
00102 uint8_t *y_plane, *cr_plane, *cb_plane;
00103 int i;
00104
00105 y_plane = frame->data[0] + x + y * frame->linesize[0];
00106 cr_plane = frame->data[1] + (x / 4) + (y / 4) * frame->linesize[1];
00107 cb_plane = frame->data[2] + (x / 4) + (y / 4) * frame->linesize[2];
00108
00109 cr_plane[0] = ulti_chromas[chroma >> 4];
00110
00111 cb_plane[0] = ulti_chromas[chroma & 0xF];
00112
00113
00114 for(i = 0; i < 16; i++){
00115 y_plane[i & 3] = ulti_lumas[luma[i]];
00116 if((i & 3) == 3) {
00117 y_plane += frame->linesize[0];
00118 }
00119 }
00120 }
00121
00122
00123 static void ulti_pattern(AVFrame *frame, int x, int y,
00124 int f0, int f1, int Y0, int Y1, int chroma)
00125 {
00126 uint8_t Luma[16];
00127 int mask, i;
00128 for(mask = 0x80, i = 0; mask; mask >>= 1, i++) {
00129 if(f0 & mask)
00130 Luma[i] = Y1;
00131 else
00132 Luma[i] = Y0;
00133 }
00134
00135 for(mask = 0x80, i = 8; mask; mask >>= 1, i++) {
00136 if(f1 & mask)
00137 Luma[i] = Y1;
00138 else
00139 Luma[i] = Y0;
00140 }
00141
00142 ulti_convert_yuv(frame, x, y, Luma, chroma);
00143 }
00144
00145
00146 static void ulti_grad(AVFrame *frame, int x, int y, uint8_t *Y, int chroma, int angle)
00147 {
00148 uint8_t Luma[16];
00149 if(angle & 8) {
00150 int t;
00151 angle &= 0x7;
00152 t = Y[0];
00153 Y[0] = Y[3];
00154 Y[3] = t;
00155 t = Y[1];
00156 Y[1] = Y[2];
00157 Y[2] = t;
00158 }
00159 switch(angle){
00160 case 0:
00161 Luma[0] = Y[0]; Luma[1] = Y[1]; Luma[2] = Y[2]; Luma[3] = Y[3];
00162 Luma[4] = Y[0]; Luma[5] = Y[1]; Luma[6] = Y[2]; Luma[7] = Y[3];
00163 Luma[8] = Y[0]; Luma[9] = Y[1]; Luma[10] = Y[2]; Luma[11] = Y[3];
00164 Luma[12] = Y[0]; Luma[13] = Y[1]; Luma[14] = Y[2]; Luma[15] = Y[3];
00165 break;
00166 case 1:
00167 Luma[0] = Y[1]; Luma[1] = Y[2]; Luma[2] = Y[3]; Luma[3] = Y[3];
00168 Luma[4] = Y[0]; Luma[5] = Y[1]; Luma[6] = Y[2]; Luma[7] = Y[3];
00169 Luma[8] = Y[0]; Luma[9] = Y[1]; Luma[10] = Y[2]; Luma[11] = Y[3];
00170 Luma[12] = Y[0]; Luma[13] = Y[0]; Luma[14] = Y[1]; Luma[15] = Y[2];
00171 break;
00172 case 2:
00173 Luma[0] = Y[1]; Luma[1] = Y[2]; Luma[2] = Y[3]; Luma[3] = Y[3];
00174 Luma[4] = Y[1]; Luma[5] = Y[2]; Luma[6] = Y[2]; Luma[7] = Y[3];
00175 Luma[8] = Y[0]; Luma[9] = Y[1]; Luma[10] = Y[1]; Luma[11] = Y[2];
00176 Luma[12] = Y[0]; Luma[13] = Y[0]; Luma[14] = Y[1]; Luma[15] = Y[2];
00177 break;
00178 case 3:
00179 Luma[0] = Y[2]; Luma[1] = Y[3]; Luma[2] = Y[3]; Luma[3] = Y[3];
00180 Luma[4] = Y[1]; Luma[5] = Y[2]; Luma[6] = Y[2]; Luma[7] = Y[3];
00181 Luma[8] = Y[0]; Luma[9] = Y[1]; Luma[10] = Y[1]; Luma[11] = Y[2];
00182 Luma[12] = Y[0]; Luma[13] = Y[0]; Luma[14] = Y[0]; Luma[15] = Y[1];
00183 break;
00184 case 4:
00185 Luma[0] = Y[3]; Luma[1] = Y[3]; Luma[2] = Y[3]; Luma[3] = Y[3];
00186 Luma[4] = Y[2]; Luma[5] = Y[2]; Luma[6] = Y[2]; Luma[7] = Y[2];
00187 Luma[8] = Y[1]; Luma[9] = Y[1]; Luma[10] = Y[1]; Luma[11] = Y[1];
00188 Luma[12] = Y[0]; Luma[13] = Y[0]; Luma[14] = Y[0]; Luma[15] = Y[0];
00189 break;
00190 case 5:
00191 Luma[0] = Y[3]; Luma[1] = Y[3]; Luma[2] = Y[3]; Luma[3] = Y[2];
00192 Luma[4] = Y[3]; Luma[5] = Y[2]; Luma[6] = Y[2]; Luma[7] = Y[1];
00193 Luma[8] = Y[2]; Luma[9] = Y[1]; Luma[10] = Y[1]; Luma[11] = Y[0];
00194 Luma[12] = Y[1]; Luma[13] = Y[0]; Luma[14] = Y[0]; Luma[15] = Y[0];
00195 break;
00196 case 6:
00197 Luma[0] = Y[3]; Luma[1] = Y[3]; Luma[2] = Y[2]; Luma[3] = Y[2];
00198 Luma[4] = Y[3]; Luma[5] = Y[2]; Luma[6] = Y[1]; Luma[7] = Y[1];
00199 Luma[8] = Y[2]; Luma[9] = Y[2]; Luma[10] = Y[1]; Luma[11] = Y[0];
00200 Luma[12] = Y[1]; Luma[13] = Y[1]; Luma[14] = Y[0]; Luma[15] = Y[0];
00201 break;
00202 case 7:
00203 Luma[0] = Y[3]; Luma[1] = Y[3]; Luma[2] = Y[2]; Luma[3] = Y[1];
00204 Luma[4] = Y[3]; Luma[5] = Y[2]; Luma[6] = Y[1]; Luma[7] = Y[0];
00205 Luma[8] = Y[3]; Luma[9] = Y[2]; Luma[10] = Y[1]; Luma[11] = Y[0];
00206 Luma[12] = Y[2]; Luma[13] = Y[1]; Luma[14] = Y[0]; Luma[15] = Y[0];
00207 break;
00208 default:
00209 Luma[0] = Y[0]; Luma[1] = Y[0]; Luma[2] = Y[1]; Luma[3] = Y[1];
00210 Luma[4] = Y[0]; Luma[5] = Y[0]; Luma[6] = Y[1]; Luma[7] = Y[1];
00211 Luma[8] = Y[2]; Luma[9] = Y[2]; Luma[10] = Y[3]; Luma[11] = Y[3];
00212 Luma[12] = Y[2]; Luma[13] = Y[2]; Luma[14] = Y[3]; Luma[15] = Y[3];
00213 break;
00214 }
00215
00216 ulti_convert_yuv(frame, x, y, Luma, chroma);
00217 }
00218
00219 static int ulti_decode_frame(AVCodecContext *avctx,
00220 void *data, int *data_size,
00221 AVPacket *avpkt)
00222 {
00223 const uint8_t *buf = avpkt->data;
00224 int buf_size = avpkt->size;
00225 UltimotionDecodeContext *s=avctx->priv_data;
00226 int modifier = 0;
00227 int uniq = 0;
00228 int mode = 0;
00229 int blocks = 0;
00230 int done = 0;
00231 int x = 0, y = 0;
00232 int i;
00233 int skip;
00234 int tmp;
00235 const uint8_t *buf_end = buf + buf_size;
00236
00237 s->frame.reference = 3;
00238 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00239 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00240 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00241 return -1;
00242 }
00243
00244 while(!done) {
00245 int idx;
00246 if(blocks >= s->blocks || y >= s->height)
00247 break;
00248
00249 CHECK_OVERREAD_SIZE(1);
00250 idx = *buf++;
00251 if((idx & 0xF8) == 0x70) {
00252 switch(idx) {
00253 case 0x70:
00254 CHECK_OVERREAD_SIZE(1);
00255 modifier = *buf++;
00256 if(modifier>1)
00257 av_log(avctx, AV_LOG_INFO, "warning: modifier must be 0 or 1, got %i\n", modifier);
00258 break;
00259 case 0x71:
00260 uniq = 1;
00261 break;
00262 case 0x72:
00263 mode = !mode;
00264 break;
00265 case 0x73:
00266 done = 1;
00267 break;
00268 case 0x74:
00269 CHECK_OVERREAD_SIZE(1);
00270 skip = *buf++;
00271 if ((blocks + skip) >= s->blocks)
00272 break;
00273 blocks += skip;
00274 x += skip * 8;
00275 while(x >= s->width) {
00276 x -= s->width;
00277 y += 8;
00278 }
00279 break;
00280 default:
00281 av_log(avctx, AV_LOG_INFO, "warning: unknown escape 0x%02X\n", idx);
00282 }
00283 } else {
00284 int code;
00285 int cf;
00286 int angle = 0;
00287 uint8_t Y[4];
00288 int tx = 0, ty = 0;
00289 int chroma = 0;
00290 if (mode || uniq) {
00291 uniq = 0;
00292 cf = 1;
00293 chroma = 0;
00294 } else {
00295 cf = 0;
00296 if (idx) {
00297 CHECK_OVERREAD_SIZE(1);
00298 chroma = *buf++;
00299 }
00300 }
00301 for (i = 0; i < 4; i++) {
00302 code = (idx >> (6 - i*2)) & 3;
00303 if(!code)
00304 continue;
00305 if(cf) {
00306 CHECK_OVERREAD_SIZE(1);
00307 chroma = *buf++;
00308 }
00309 tx = x + block_coords[i * 2];
00310 ty = y + block_coords[(i * 2) + 1];
00311 switch(code) {
00312 case 1:
00313 CHECK_OVERREAD_SIZE(1);
00314 tmp = *buf++;
00315
00316 angle = angle_by_index[(tmp >> 6) & 0x3];
00317
00318 Y[0] = tmp & 0x3F;
00319 Y[1] = Y[0];
00320
00321 if (angle) {
00322 Y[2] = Y[0]+1;
00323 if (Y[2] > 0x3F)
00324 Y[2] = 0x3F;
00325 Y[3] = Y[2];
00326 } else {
00327 Y[2] = Y[0];
00328 Y[3] = Y[0];
00329 }
00330 break;
00331
00332 case 2:
00333 if (modifier) {
00334 CHECK_OVERREAD_SIZE(3);
00335 tmp = bytestream_get_be24(&buf);
00336
00337 Y[0] = (tmp >> 18) & 0x3F;
00338 Y[1] = (tmp >> 12) & 0x3F;
00339 Y[2] = (tmp >> 6) & 0x3F;
00340 Y[3] = tmp & 0x3F;
00341 angle = 16;
00342 } else {
00343 CHECK_OVERREAD_SIZE(2);
00344 tmp = bytestream_get_be16(&buf);
00345
00346 angle = (tmp >> 12) & 0xF;
00347 tmp &= 0xFFF;
00348 tmp <<= 2;
00349 Y[0] = s->ulti_codebook[tmp];
00350 Y[1] = s->ulti_codebook[tmp + 1];
00351 Y[2] = s->ulti_codebook[tmp + 2];
00352 Y[3] = s->ulti_codebook[tmp + 3];
00353 }
00354 break;
00355
00356 case 3:
00357 if (modifier) {
00358 uint8_t Luma[16];
00359
00360 CHECK_OVERREAD_SIZE(12);
00361
00362 tmp = bytestream_get_be24(&buf);
00363 Luma[0] = (tmp >> 18) & 0x3F;
00364 Luma[1] = (tmp >> 12) & 0x3F;
00365 Luma[2] = (tmp >> 6) & 0x3F;
00366 Luma[3] = tmp & 0x3F;
00367
00368 tmp = bytestream_get_be24(&buf);
00369 Luma[4] = (tmp >> 18) & 0x3F;
00370 Luma[5] = (tmp >> 12) & 0x3F;
00371 Luma[6] = (tmp >> 6) & 0x3F;
00372 Luma[7] = tmp & 0x3F;
00373
00374 tmp = bytestream_get_be24(&buf);
00375 Luma[8] = (tmp >> 18) & 0x3F;
00376 Luma[9] = (tmp >> 12) & 0x3F;
00377 Luma[10] = (tmp >> 6) & 0x3F;
00378 Luma[11] = tmp & 0x3F;
00379
00380 tmp = bytestream_get_be24(&buf);
00381 Luma[12] = (tmp >> 18) & 0x3F;
00382 Luma[13] = (tmp >> 12) & 0x3F;
00383 Luma[14] = (tmp >> 6) & 0x3F;
00384 Luma[15] = tmp & 0x3F;
00385
00386 ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma);
00387 } else {
00388 CHECK_OVERREAD_SIZE(4);
00389 tmp = *buf++;
00390 if(tmp & 0x80) {
00391 angle = (tmp >> 4) & 0x7;
00392 tmp = (tmp << 8) + *buf++;
00393 Y[0] = (tmp >> 6) & 0x3F;
00394 Y[1] = tmp & 0x3F;
00395 Y[2] = (*buf++) & 0x3F;
00396 Y[3] = (*buf++) & 0x3F;
00397 ulti_grad(&s->frame, tx, ty, Y, chroma, angle);
00398 } else {
00399 int f0, f1;
00400 f0 = *buf++;
00401 f1 = tmp;
00402 Y[0] = (*buf++) & 0x3F;
00403 Y[1] = (*buf++) & 0x3F;
00404 ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma);
00405 }
00406 }
00407 break;
00408 }
00409 if(code != 3)
00410 ulti_grad(&s->frame, tx, ty, Y, chroma, angle);
00411 }
00412 blocks++;
00413 x += 8;
00414 if(x >= s->width) {
00415 x = 0;
00416 y += 8;
00417 }
00418 }
00419 }
00420
00421 *data_size=sizeof(AVFrame);
00422 *(AVFrame*)data= s->frame;
00423
00424 return buf_size;
00425 }
00426
00427 AVCodec ff_ulti_decoder = {
00428 .name = "ultimotion",
00429 .type = AVMEDIA_TYPE_VIDEO,
00430 .id = CODEC_ID_ULTI,
00431 .priv_data_size = sizeof(UltimotionDecodeContext),
00432 .init = ulti_decode_init,
00433 .close = ulti_decode_end,
00434 .decode = ulti_decode_frame,
00435 .capabilities = CODEC_CAP_DR1,
00436 .long_name = NULL_IF_CONFIG_SMALL("IBM UltiMotion"),
00437 };
00438