Mercurial > libavcodec.hg
comparison mjpeg.c @ 1310:b76927543aaf libavcodec
cleanup
pegasus "pseudo yuv" (=RCT) lossless decoding support
bigendian fix?
author | michaelni |
---|---|
date | Mon, 16 Jun 2003 13:19:30 +0000 |
parents | 26bed13dd48d |
children | 899c8f52094c |
comparison
equal
deleted
inserted
replaced
1309:0cfdbbf84a6c | 1310:b76927543aaf |
---|---|
279 void mjpeg_close(MpegEncContext *s) | 279 void mjpeg_close(MpegEncContext *s) |
280 { | 280 { |
281 av_free(s->mjpeg_ctx); | 281 av_free(s->mjpeg_ctx); |
282 } | 282 } |
283 | 283 |
284 static inline int predict(uint8_t *ptr, int stride, int predictor, int size){ | 284 #define PREDICT(ret, topleft, top, left, predictor)\ |
285 switch(predictor){ | 285 switch(predictor){\ |
286 case 0: return ptr[0]; | 286 case 1: ret= left; break;\ |
287 case 1: return ptr[-size]; | 287 case 2: ret= top; break;\ |
288 case 2: return ptr[-stride]; | 288 case 3: ret= topleft; break;\ |
289 case 3: return ptr[-stride-size]; | 289 case 4: ret= left + top - topleft; break;\ |
290 case 4: return ptr[-size] + ptr[-stride] - ptr[-stride-size]; | 290 case 5: ret= left + ((top - topleft)>>1); break;\ |
291 case 5: return ptr[-size] + ((ptr[-stride] - ptr[-stride-size])>>1); | 291 case 6: ret= top + ((left - topleft)>>1); break;\ |
292 case 6: return ptr[-stride] + ((ptr[-size] - ptr[-stride-size])>>1); | 292 case 7: ret= (left + top)>>1; break;\ |
293 case 7: return (ptr[-size] + ptr[-stride])>>1; | 293 } |
294 default: return 0xFFFF; | |
295 } | |
296 } | |
297 | 294 |
298 static inline void put_marker(PutBitContext *p, int code) | 295 static inline void put_marker(PutBitContext *p, int code) |
299 { | 296 { |
300 put_bits(p, 8, 0xff); | 297 put_bits(p, 8, 0xff); |
301 put_bits(p, 8, code); | 298 put_bits(p, 8, code); |
669 int first_picture; /* true if decoding first picture */ | 666 int first_picture; /* true if decoding first picture */ |
670 int interlaced; /* true if interlaced */ | 667 int interlaced; /* true if interlaced */ |
671 int bottom_field; /* true if bottom field */ | 668 int bottom_field; /* true if bottom field */ |
672 int lossless; | 669 int lossless; |
673 int rgb; | 670 int rgb; |
671 int rct; /* pegasus reversible colorspace transform */ | |
672 int bits; /* bits per component */ | |
674 | 673 |
675 int width, height; | 674 int width, height; |
676 int nb_components; | 675 int nb_components; |
677 int component_id[MAX_COMPONENTS]; | 676 int component_id[MAX_COMPONENTS]; |
678 int h_count[MAX_COMPONENTS]; /* horizontal and vertical count for each component */ | 677 int h_count[MAX_COMPONENTS]; /* horizontal and vertical count for each component */ |
832 { | 831 { |
833 int len, nb_components, i, width, height; | 832 int len, nb_components, i, width, height; |
834 | 833 |
835 /* XXX: verify len field validity */ | 834 /* XXX: verify len field validity */ |
836 len = get_bits(&s->gb, 16); | 835 len = get_bits(&s->gb, 16); |
837 if (get_bits(&s->gb, 8) != 8){ | 836 s->bits= get_bits(&s->gb, 8); |
837 if(s->rct) s->bits=9; | |
838 | |
839 if (s->bits != 8 && !s->lossless){ | |
838 printf("only 8 bits/component accepted\n"); | 840 printf("only 8 bits/component accepted\n"); |
839 return -1; | 841 return -1; |
840 } | 842 } |
841 height = get_bits(&s->gb, 16); | 843 height = get_bits(&s->gb, 16); |
842 width = get_bits(&s->gb, 16); | 844 width = get_bits(&s->gb, 16); |
863 if (s->quant_index[i] >= 4) | 865 if (s->quant_index[i] >= 4) |
864 return -1; | 866 return -1; |
865 dprintf("component %d %d:%d id: %d quant:%d\n", i, s->h_count[i], | 867 dprintf("component %d %d:%d id: %d quant:%d\n", i, s->h_count[i], |
866 s->v_count[i], s->component_id[i], s->quant_index[i]); | 868 s->v_count[i], s->component_id[i], s->quant_index[i]); |
867 } | 869 } |
870 | |
871 if(s->v_max==1 && s->h_max==1 && s->lossless==1) s->rgb=1; | |
868 | 872 |
869 /* if different size, realloc/alloc picture */ | 873 /* if different size, realloc/alloc picture */ |
870 /* XXX: also check h_count and v_count */ | 874 /* XXX: also check h_count and v_count */ |
871 if (width != s->width || height != s->height) { | 875 if (width != s->width || height != s->height) { |
872 for(i=0;i<MAX_COMPONENTS;i++) | 876 for(i=0;i<MAX_COMPONENTS;i++) |
880 s->interlaced = 1; | 884 s->interlaced = 1; |
881 // s->bottom_field = (s->interlace_polarity) ? 1 : 0; | 885 // s->bottom_field = (s->interlace_polarity) ? 1 : 0; |
882 s->bottom_field = 0; | 886 s->bottom_field = 0; |
883 } | 887 } |
884 | 888 |
885 assert(s->rgb==0 || (s->h_max==1 && s->v_max==1)); | |
886 if(s->rgb){ | 889 if(s->rgb){ |
887 int w, h; | 890 int w, h; |
888 w = s->width; | 891 w = s->width; |
889 h = s->height; | 892 h = s->height; |
890 if (s->interlaced) | 893 if (s->interlaced) |
1031 dprintf("decode_sos: index(%d) out of components\n", index); | 1034 dprintf("decode_sos: index(%d) out of components\n", index); |
1032 return -1; | 1035 return -1; |
1033 } | 1036 } |
1034 | 1037 |
1035 comp_index[i] = index; | 1038 comp_index[i] = index; |
1039 | |
1036 nb_blocks[i] = s->h_count[index] * s->v_count[index]; | 1040 nb_blocks[i] = s->h_count[index] * s->v_count[index]; |
1037 h_count[i] = s->h_count[index]; | 1041 h_count[i] = s->h_count[index]; |
1038 v_count[i] = s->v_count[index]; | 1042 v_count[i] = s->v_count[index]; |
1039 | 1043 |
1040 dc_index[i] = get_bits(&s->gb, 4); | 1044 dc_index[i] = get_bits(&s->gb, 4); |
1058 if (dc_index[i] > 3 || ac_index[i] != 0) | 1062 if (dc_index[i] > 3 || ac_index[i] != 0) |
1059 goto out_of_range; | 1063 goto out_of_range; |
1060 break; | 1064 break; |
1061 } | 1065 } |
1062 } | 1066 } |
1067 | |
1063 predictor= get_bits(&s->gb, 8); /* lossless predictor or start of spectral (Ss) */ | 1068 predictor= get_bits(&s->gb, 8); /* lossless predictor or start of spectral (Ss) */ |
1064 skip_bits(&s->gb, 8); /* Se */ | 1069 skip_bits(&s->gb, 8); /* Se */ |
1065 skip_bits(&s->gb, 4); /* Ah */ | 1070 skip_bits(&s->gb, 4); /* Ah */ |
1066 point_transform= get_bits(&s->gb, 4); /* Al */ | 1071 point_transform= get_bits(&s->gb, 4); /* Al */ |
1067 | 1072 |
1080 nb_blocks[0] = 1; | 1085 nb_blocks[0] = 1; |
1081 h_count[0] = 1; | 1086 h_count[0] = 1; |
1082 v_count[0] = 1; | 1087 v_count[0] = 1; |
1083 } | 1088 } |
1084 | 1089 |
1090 if(s->avctx->debug & FF_DEBUG_PICT_INFO) | |
1091 printf("%s %s p:%d >>:%d\n", s->lossless ? "lossless" : "sequencial DCT", s->rgb ? "RGB" : "", predictor, point_transform); | |
1092 | |
1085 if(s->lossless){ | 1093 if(s->lossless){ |
1086 if(s->rgb){ //FIXME cleanup | 1094 if(s->rgb){ |
1095 uint16_t buffer[2048][4]; | |
1096 int left[3], top[3], topleft[3]; | |
1087 const int linesize= s->linesize[0]; | 1097 const int linesize= s->linesize[0]; |
1098 const int mask= (1<<s->bits)-1; | |
1099 | |
1100 for(i=0; i<3; i++){ | |
1101 buffer[0][i]= 1 << (s->bits + point_transform - 1); | |
1102 } | |
1088 for(mb_y = 0; mb_y < mb_height; mb_y++) { | 1103 for(mb_y = 0; mb_y < mb_height; mb_y++) { |
1104 const int modified_predictor= mb_y ? 1 : predictor; | |
1105 uint8_t *ptr = s->current_picture[0] + (linesize * mb_y); | |
1106 | |
1107 if (s->interlaced && s->bottom_field) | |
1108 ptr += linesize >> 1; | |
1109 | |
1110 for(i=0; i<3; i++){ | |
1111 top[i]= left[i]= topleft[i]= buffer[0][i]; | |
1112 } | |
1089 for(mb_x = 0; mb_x < mb_width; mb_x++) { | 1113 for(mb_x = 0; mb_x < mb_width; mb_x++) { |
1090 if (s->restart_interval && !s->restart_count) | 1114 if (s->restart_interval && !s->restart_count) |
1091 s->restart_count = s->restart_interval; | 1115 s->restart_count = s->restart_interval; |
1092 | 1116 |
1093 if(mb_x==0 || mb_y==0 || s->interlaced || 1){ | 1117 for(i=0;i<3;i++) { |
1094 for(i=0;i<3;i++) { | 1118 int pred; |
1095 uint8_t *ptr; | 1119 |
1096 int c, pred; | 1120 PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); |
1097 c = comp_index[i]; | 1121 |
1098 | 1122 topleft[i]= top[i]; |
1099 ptr = s->current_picture[0] + (linesize * mb_y) + 4*mb_x + c; //FIXME optimize this crap | 1123 top[i]= buffer[mb_x][i]; |
1100 if(mb_y==0){ | 1124 |
1101 if(mb_x==0){ | 1125 left[i]= |
1102 pred= 128 << point_transform; | 1126 buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform)); |
1103 }else{ | |
1104 pred= ptr[-4]; | |
1105 } | |
1106 }else{ | |
1107 if(mb_x==0){ | |
1108 pred= ptr[-linesize]; | |
1109 }else{ | |
1110 pred= predict(ptr, linesize, predictor, 4); | |
1111 } | |
1112 } | |
1113 if (s->interlaced && s->bottom_field) | |
1114 ptr += linesize >> 1; | |
1115 *ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform); | |
1116 } | |
1117 }else{ | |
1118 for(i=0;i<3;i++) { | |
1119 uint8_t *ptr; | |
1120 int c, pred; | |
1121 c = comp_index[i]; | |
1122 | |
1123 ptr = s->current_picture[0] + (linesize * mb_y) + 4*mb_x + c; //FIXME optimize this crap | |
1124 pred= predict(ptr, linesize, predictor, 4); | |
1125 *ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform); | |
1126 } | |
1127 } | 1127 } |
1128 /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */ | 1128 |
1129 if (s->restart_interval && (s->restart_interval < 1350) && | 1129 if (s->restart_interval && !--s->restart_count) { |
1130 !--s->restart_count) { | |
1131 align_get_bits(&s->gb); | 1130 align_get_bits(&s->gb); |
1132 skip_bits(&s->gb, 16); /* skip RSTn */ | 1131 skip_bits(&s->gb, 16); /* skip RSTn */ |
1132 } | |
1133 } | |
1134 | |
1135 if(s->rct){ | |
1136 for(mb_x = 0; mb_x < mb_width; mb_x++) { | |
1137 ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2])>>2); | |
1138 ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1]; | |
1139 ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; | |
1140 } | |
1141 }else{ | |
1142 for(mb_x = 0; mb_x < mb_width; mb_x++) { | |
1143 ptr[4*mb_x+0] = buffer[mb_x][0]; | |
1144 ptr[4*mb_x+1] = buffer[mb_x][1]; | |
1145 ptr[4*mb_x+2] = buffer[mb_x][2]; | |
1133 } | 1146 } |
1134 } | 1147 } |
1135 } | 1148 } |
1136 }else{ | 1149 }else{ |
1137 for(mb_y = 0; mb_y < mb_height; mb_y++) { | 1150 for(mb_y = 0; mb_y < mb_height; mb_y++) { |
1138 for(mb_x = 0; mb_x < mb_width; mb_x++) { | 1151 for(mb_x = 0; mb_x < mb_width; mb_x++) { |
1139 if (s->restart_interval && !s->restart_count) | 1152 if (s->restart_interval && !s->restart_count) |
1140 s->restart_count = s->restart_interval; | 1153 s->restart_count = s->restart_interval; |
1141 | 1154 |
1142 if(mb_x==0 || mb_y==0 || s->interlaced || 1){ | 1155 if(mb_x==0 || mb_y==0 || s->interlaced){ |
1143 for(i=0;i<nb_components;i++) { | 1156 for(i=0;i<nb_components;i++) { |
1144 uint8_t *ptr; | 1157 uint8_t *ptr; |
1145 int x, y, c, linesize; | 1158 int x, y, c, linesize; |
1146 n = nb_blocks[i]; | 1159 n = nb_blocks[i]; |
1147 c = comp_index[i]; | 1160 c = comp_index[i]; |
1163 } | 1176 } |
1164 }else{ | 1177 }else{ |
1165 if(x==0 && mb_x==0){ | 1178 if(x==0 && mb_x==0){ |
1166 pred= ptr[-linesize]; | 1179 pred= ptr[-linesize]; |
1167 }else{ | 1180 }else{ |
1168 pred= predict(ptr, linesize, predictor, 1); | 1181 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); |
1169 } | 1182 } |
1170 } | 1183 } |
1171 | 1184 |
1172 if (s->interlaced && s->bottom_field) | 1185 if (s->interlaced && s->bottom_field) |
1173 ptr += linesize >> 1; | 1186 ptr += linesize >> 1; |
1193 | 1206 |
1194 for(j=0; j<n; j++) { | 1207 for(j=0; j<n; j++) { |
1195 int pred; | 1208 int pred; |
1196 | 1209 |
1197 ptr = s->current_picture[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap | 1210 ptr = s->current_picture[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap |
1198 pred= predict(ptr, linesize, predictor, 1); | 1211 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); |
1199 *ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform); | 1212 *ptr= pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform); |
1200 if (++x == h) { | 1213 if (++x == h) { |
1201 x = 0; | 1214 x = 0; |
1202 y++; | 1215 y++; |
1203 } | 1216 } |
1204 } | 1217 } |
1205 } | 1218 } |
1206 } | 1219 } |
1207 /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */ | 1220 if (s->restart_interval && !--s->restart_count) { |
1208 if (s->restart_interval && (s->restart_interval < 1350) && | |
1209 !--s->restart_count) { | |
1210 align_get_bits(&s->gb); | 1221 align_get_bits(&s->gb); |
1211 skip_bits(&s->gb, 16); /* skip RSTn */ | 1222 skip_bits(&s->gb, 16); /* skip RSTn */ |
1212 } | 1223 } |
1213 } | 1224 } |
1214 } | 1225 } |
1291 | 1302 |
1292 id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); | 1303 id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); |
1293 id = be2me_32(id); | 1304 id = be2me_32(id); |
1294 len -= 6; | 1305 len -= 6; |
1295 | 1306 |
1307 if(s->avctx->debug & FF_DEBUG_STARTCODE){ | |
1308 printf("APPx %8X\n", id); | |
1309 } | |
1310 | |
1296 /* buggy AVID, it puts EOI only at every 10th frame */ | 1311 /* buggy AVID, it puts EOI only at every 10th frame */ |
1297 /* also this fourcc is used by non-avid files too, it holds some | 1312 /* also this fourcc is used by non-avid files too, it holds some |
1298 informations, but it's always present in AVID creates files */ | 1313 informations, but it's always present in AVID creates files */ |
1299 if (id == ff_get_fourcc("AVI1")) | 1314 if (id == ff_get_fourcc("AVI1")) |
1300 { | 1315 { |
1371 skip_bits(&s->gb, 16); /* flags0 */ | 1386 skip_bits(&s->gb, 16); /* flags0 */ |
1372 skip_bits(&s->gb, 16); /* flags1 */ | 1387 skip_bits(&s->gb, 16); /* flags1 */ |
1373 skip_bits(&s->gb, 8); /* transform */ | 1388 skip_bits(&s->gb, 8); /* transform */ |
1374 len -= 7; | 1389 len -= 7; |
1375 goto out; | 1390 goto out; |
1391 } | |
1392 | |
1393 if (id == ff_get_fourcc("LJIF")){ | |
1394 printf("Pegasus lossless jpeg header found\n"); | |
1395 int i; | |
1396 skip_bits(&s->gb, 16); /* version ? */ | |
1397 skip_bits(&s->gb, 16); /* unknwon always 0? */ | |
1398 skip_bits(&s->gb, 16); /* unknwon always 0? */ | |
1399 skip_bits(&s->gb, 16); /* unknwon always 0? */ | |
1400 switch( get_bits(&s->gb, 8)){ | |
1401 case 1: | |
1402 s->rgb= 1; | |
1403 s->rct=0; | |
1404 break; | |
1405 case 2: | |
1406 s->rgb= 1; | |
1407 s->rct=1; | |
1408 break; | |
1409 default: | |
1410 printf("unknown colorspace\n"); | |
1411 } | |
1412 len -= 9; | |
1413 goto out; | |
1376 } | 1414 } |
1377 | 1415 |
1378 /* Apple MJPEG-A */ | 1416 /* Apple MJPEG-A */ |
1379 if ((s->start_code == APP1) && (len > (0x28 - 8))) | 1417 if ((s->start_code == APP1) && (len > (0x28 - 8))) |
1380 { | 1418 { |
1561 } | 1599 } |
1562 else | 1600 else |
1563 init_get_bits(&s->gb, buf_ptr, (buf_end - buf_ptr)*8); | 1601 init_get_bits(&s->gb, buf_ptr, (buf_end - buf_ptr)*8); |
1564 | 1602 |
1565 s->start_code = start_code; | 1603 s->start_code = start_code; |
1604 if(s->avctx->debug & FF_DEBUG_STARTCODE){ | |
1605 printf("startcode: %X\n", start_code); | |
1606 } | |
1566 | 1607 |
1567 /* process markers */ | 1608 /* process markers */ |
1568 if (start_code >= 0xd0 && start_code <= 0xd7) { | 1609 if (start_code >= 0xd0 && start_code <= 0xd7) { |
1569 dprintf("restart marker: %d\n", start_code&0x0f); | 1610 dprintf("restart marker: %d\n", start_code&0x0f); |
1570 } else if (s->first_picture) { | 1611 } else if (s->first_picture) { |
1587 case DHT: | 1628 case DHT: |
1588 mjpeg_decode_dht(s); | 1629 mjpeg_decode_dht(s); |
1589 break; | 1630 break; |
1590 case SOF0: | 1631 case SOF0: |
1591 s->lossless=0; | 1632 s->lossless=0; |
1592 s->rgb=0; | |
1593 if (mjpeg_decode_sof(s) < 0) | 1633 if (mjpeg_decode_sof(s) < 0) |
1594 return -1; | 1634 return -1; |
1595 break; | 1635 break; |
1596 case SOF3: | 1636 case SOF3: |
1597 s->lossless=1; | 1637 s->lossless=1; |
1598 s->rgb=1; //FIXME | |
1599 if (mjpeg_decode_sof(s) < 0) | 1638 if (mjpeg_decode_sof(s) < 0) |
1600 return -1; | 1639 return -1; |
1601 break; | 1640 break; |
1602 case EOI: | 1641 case EOI: |
1603 eoi_parser: | 1642 eoi_parser: |
1620 avctx->width = s->width; | 1659 avctx->width = s->width; |
1621 /* XXX: not complete test ! */ | 1660 /* XXX: not complete test ! */ |
1622 switch((s->h_count[0] << 4) | s->v_count[0]) { | 1661 switch((s->h_count[0] << 4) | s->v_count[0]) { |
1623 case 0x11: | 1662 case 0x11: |
1624 if(s->rgb){ | 1663 if(s->rgb){ |
1664 #ifdef WORDS_BIGENDIAN | |
1665 avctx->pix_fmt = PIX_FMT_ABGR32; | |
1666 #else | |
1625 avctx->pix_fmt = PIX_FMT_RGBA32; | 1667 avctx->pix_fmt = PIX_FMT_RGBA32; |
1668 #endif | |
1626 }else | 1669 }else |
1627 avctx->pix_fmt = PIX_FMT_YUV444P; | 1670 avctx->pix_fmt = PIX_FMT_YUV444P; |
1628 break; | 1671 break; |
1629 case 0x21: | 1672 case 0x21: |
1630 avctx->pix_fmt = PIX_FMT_YUV422P; | 1673 avctx->pix_fmt = PIX_FMT_YUV422P; |