Mercurial > libavcodec.hg
comparison mjpeg.c @ 1315:6696d3bf4ff2 libavcodec
lossless mjpeg encoding (planar yuv & RGB) and somerelated bugfixes
author | michaelni |
---|---|
date | Tue, 17 Jun 2003 22:48:51 +0000 |
parents | 899c8f52094c |
children | f78341ab5fba |
comparison
equal
deleted
inserted
replaced
1314:8a7be8c2710e | 1315:6696d3bf4ff2 |
---|---|
36 /* use two quantizer tables (one for luminance and one for chrominance) */ | 36 /* use two quantizer tables (one for luminance and one for chrominance) */ |
37 /* not yet working */ | 37 /* not yet working */ |
38 #undef TWOMATRIXES | 38 #undef TWOMATRIXES |
39 | 39 |
40 typedef struct MJpegContext { | 40 typedef struct MJpegContext { |
41 uint8_t huff_size_dc_luminance[12]; | 41 uint8_t huff_size_dc_luminance[12]; //FIXME use array [3] instead of lumi / chrom, for easier addressing |
42 uint16_t huff_code_dc_luminance[12]; | 42 uint16_t huff_code_dc_luminance[12]; |
43 uint8_t huff_size_dc_chrominance[12]; | 43 uint8_t huff_size_dc_chrominance[12]; |
44 uint16_t huff_code_dc_chrominance[12]; | 44 uint16_t huff_code_dc_chrominance[12]; |
45 | 45 |
46 uint8_t huff_size_ac_luminance[256]; | 46 uint8_t huff_size_ac_luminance[256]; |
367 { | 367 { |
368 PutBitContext *p = &s->pb; | 368 PutBitContext *p = &s->pb; |
369 int size; | 369 int size; |
370 uint8_t *ptr; | 370 uint8_t *ptr; |
371 | 371 |
372 if (s->aspect_ratio_info) | 372 if (s->aspect_ratio_info /* && !lossless */) |
373 { | 373 { |
374 /* JFIF header */ | 374 /* JFIF header */ |
375 put_marker(p, APP0); | 375 put_marker(p, APP0); |
376 put_bits(p, 16, 16); | 376 put_bits(p, 16, 16); |
377 put_string(p, "JFIF"); /* this puts the trailing zero-byte too */ | 377 put_string(p, "JFIF"); /* this puts the trailing zero-byte too */ |
416 } | 416 } |
417 } | 417 } |
418 | 418 |
419 void mjpeg_picture_header(MpegEncContext *s) | 419 void mjpeg_picture_header(MpegEncContext *s) |
420 { | 420 { |
421 const int lossless= s->avctx->codec_id == CODEC_ID_LJPEG; | |
422 | |
421 put_marker(&s->pb, SOI); | 423 put_marker(&s->pb, SOI); |
422 | 424 |
423 if (!s->mjpeg_data_only_frames) | 425 if (!s->mjpeg_data_only_frames) |
424 { | 426 { |
425 jpeg_put_comments(s); | 427 jpeg_put_comments(s); |
426 | 428 |
427 if (s->mjpeg_write_tables) jpeg_table_header(s); | 429 if (s->mjpeg_write_tables) jpeg_table_header(s); |
428 | 430 |
429 put_marker(&s->pb, SOF0); | 431 put_marker(&s->pb, lossless ? SOF3 : SOF0); |
430 | 432 |
431 put_bits(&s->pb, 16, 17); | 433 put_bits(&s->pb, 16, 17); |
432 put_bits(&s->pb, 8, 8); /* 8 bits/component */ | 434 if(lossless && s->avctx->pix_fmt == PIX_FMT_RGBA32) |
435 put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */ | |
436 else | |
437 put_bits(&s->pb, 8, 8); /* 8 bits/component */ | |
433 put_bits(&s->pb, 16, s->height); | 438 put_bits(&s->pb, 16, s->height); |
434 put_bits(&s->pb, 16, s->width); | 439 put_bits(&s->pb, 16, s->width); |
435 put_bits(&s->pb, 8, 3); /* 3 components */ | 440 put_bits(&s->pb, 8, 3); /* 3 components */ |
436 | 441 |
437 /* Y component */ | 442 /* Y component */ |
443 /* Cb component */ | 448 /* Cb component */ |
444 put_bits(&s->pb, 8, 2); /* component number */ | 449 put_bits(&s->pb, 8, 2); /* component number */ |
445 put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */ | 450 put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */ |
446 put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */ | 451 put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */ |
447 #ifdef TWOMATRIXES | 452 #ifdef TWOMATRIXES |
448 put_bits(&s->pb, 8, 1); /* select matrix */ | 453 put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ |
449 #else | 454 #else |
450 put_bits(&s->pb, 8, 0); /* select matrix */ | 455 put_bits(&s->pb, 8, 0); /* select matrix */ |
451 #endif | 456 #endif |
452 | 457 |
453 /* Cr component */ | 458 /* Cr component */ |
454 put_bits(&s->pb, 8, 3); /* component number */ | 459 put_bits(&s->pb, 8, 3); /* component number */ |
455 put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */ | 460 put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */ |
456 put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */ | 461 put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */ |
457 #ifdef TWOMATRIXES | 462 #ifdef TWOMATRIXES |
458 put_bits(&s->pb, 8, 1); /* select matrix */ | 463 put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ |
459 #else | 464 #else |
460 put_bits(&s->pb, 8, 0); /* select matrix */ | 465 put_bits(&s->pb, 8, 0); /* select matrix */ |
461 #endif | 466 #endif |
462 } | 467 } |
463 | 468 |
472 put_bits(&s->pb, 4, 0); /* AC huffman table index */ | 477 put_bits(&s->pb, 4, 0); /* AC huffman table index */ |
473 | 478 |
474 /* Cb component */ | 479 /* Cb component */ |
475 put_bits(&s->pb, 8, 2); /* index */ | 480 put_bits(&s->pb, 8, 2); /* index */ |
476 put_bits(&s->pb, 4, 1); /* DC huffman table index */ | 481 put_bits(&s->pb, 4, 1); /* DC huffman table index */ |
477 put_bits(&s->pb, 4, 1); /* AC huffman table index */ | 482 put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ |
478 | 483 |
479 /* Cr component */ | 484 /* Cr component */ |
480 put_bits(&s->pb, 8, 3); /* index */ | 485 put_bits(&s->pb, 8, 3); /* index */ |
481 put_bits(&s->pb, 4, 1); /* DC huffman table index */ | 486 put_bits(&s->pb, 4, 1); /* DC huffman table index */ |
482 put_bits(&s->pb, 4, 1); /* AC huffman table index */ | 487 put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ |
483 | 488 |
484 put_bits(&s->pb, 8, 0); /* Ss (not used) */ | 489 put_bits(&s->pb, 8, lossless ? s->avctx->prediction_method+1 : 0); /* Ss (not used) */ |
485 put_bits(&s->pb, 8, 63); /* Se (not used) */ | 490 put_bits(&s->pb, 8, lossless ? 0 : 63); /* Se (not used) */ |
486 put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ | 491 put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ |
487 } | 492 } |
488 | 493 |
489 static void escape_FF(MpegEncContext *s, int start) | 494 static void escape_FF(MpegEncContext *s, int start) |
490 { | 495 { |
643 for(i=0;i<6;i++) { | 648 for(i=0;i<6;i++) { |
644 encode_block(s, block[i], i); | 649 encode_block(s, block[i], i); |
645 } | 650 } |
646 } | 651 } |
647 | 652 |
653 static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | |
654 MpegEncContext * const s = avctx->priv_data; | |
655 MJpegContext * const m = s->mjpeg_ctx; | |
656 AVFrame *pict = data; | |
657 const int width= s->width; | |
658 const int height= s->height; | |
659 AVFrame * const p= (AVFrame*)&s->current_picture; | |
660 const int predictor= avctx->prediction_method+1; | |
661 | |
662 init_put_bits(&s->pb, buf, buf_size, NULL, NULL); | |
663 | |
664 *p = *pict; | |
665 p->pict_type= FF_I_TYPE; | |
666 p->key_frame= 1; | |
667 | |
668 mjpeg_picture_header(s); | |
669 | |
670 s->header_bits= get_bit_count(&s->pb); | |
671 | |
672 if(avctx->pix_fmt == PIX_FMT_RGBA32){ | |
673 int x, y, i; | |
674 const int linesize= p->linesize[0]; | |
675 uint16_t buffer[2048][4]; | |
676 int left[3], top[3], topleft[3]; | |
677 | |
678 for(i=0; i<3; i++){ | |
679 buffer[0][i]= 1 << (9 - 1); | |
680 } | |
681 | |
682 for(y = 0; y < height; y++) { | |
683 const int modified_predictor= y ? 1 : predictor; | |
684 uint8_t *ptr = p->data[0] + (linesize * y); | |
685 | |
686 for(i=0; i<3; i++){ | |
687 top[i]= left[i]= topleft[i]= buffer[0][i]; | |
688 } | |
689 for(x = 0; x < width; x++) { | |
690 buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100; | |
691 buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100; | |
692 buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2; | |
693 | |
694 for(i=0;i<3;i++) { | |
695 int pred, diff; | |
696 | |
697 PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); | |
698 | |
699 topleft[i]= top[i]; | |
700 top[i]= buffer[x+1][i]; | |
701 | |
702 left[i]= buffer[x][i]; | |
703 | |
704 diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100; | |
705 | |
706 if(i==0) | |
707 mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly | |
708 else | |
709 mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); | |
710 } | |
711 } | |
712 } | |
713 }else{ | |
714 int mb_x, mb_y, i; | |
715 const int mb_width = (width + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0]; | |
716 const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0]; | |
717 | |
718 for(mb_y = 0; mb_y < mb_height; mb_y++) { | |
719 for(mb_x = 0; mb_x < mb_width; mb_x++) { | |
720 if(mb_x==0 || mb_y==0){ | |
721 for(i=0;i<3;i++) { | |
722 uint8_t *ptr; | |
723 int x, y, h, v, linesize; | |
724 h = s->mjpeg_hsample[i]; | |
725 v = s->mjpeg_vsample[i]; | |
726 linesize= p->linesize[i]; | |
727 | |
728 for(y=0; y<v; y++){ | |
729 for(x=0; x<h; x++){ | |
730 int pred; | |
731 | |
732 ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap | |
733 if(y==0 && mb_y==0){ | |
734 if(x==0 && mb_x==0){ | |
735 pred= 128; | |
736 }else{ | |
737 pred= ptr[-1]; | |
738 } | |
739 }else{ | |
740 if(x==0 && mb_x==0){ | |
741 pred= ptr[-linesize]; | |
742 }else{ | |
743 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); | |
744 } | |
745 } | |
746 | |
747 if(i==0) | |
748 mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly | |
749 else | |
750 mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); | |
751 } | |
752 } | |
753 } | |
754 }else{ | |
755 for(i=0;i<3;i++) { | |
756 uint8_t *ptr; | |
757 int x, y, h, v, linesize; | |
758 h = s->mjpeg_hsample[i]; | |
759 v = s->mjpeg_vsample[i]; | |
760 linesize= p->linesize[i]; | |
761 | |
762 for(y=0; y<v; y++){ | |
763 for(x=0; x<h; x++){ | |
764 int pred; | |
765 | |
766 ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap | |
767 //printf("%d %d %d %d %8X\n", mb_x, mb_y, x, y, ptr); | |
768 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); | |
769 | |
770 if(i==0) | |
771 mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly | |
772 else | |
773 mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); | |
774 } | |
775 } | |
776 } | |
777 } | |
778 } | |
779 } | |
780 } | |
781 | |
782 emms_c(); | |
783 | |
784 mjpeg_picture_trailer(s); | |
785 s->picture_number++; | |
786 | |
787 flush_put_bits(&s->pb); | |
788 return pbBufPtr(&s->pb) - s->pb.buf; | |
789 // return (get_bit_count(&f->pb)+7)/8; | |
790 } | |
791 | |
792 | |
648 /******************************************/ | 793 /******************************************/ |
649 /* decoding */ | 794 /* decoding */ |
650 | 795 |
651 #define MAX_COMPONENTS 4 | 796 #define MAX_COMPONENTS 4 |
652 | 797 |
666 int first_picture; /* true if decoding first picture */ | 811 int first_picture; /* true if decoding first picture */ |
667 int interlaced; /* true if interlaced */ | 812 int interlaced; /* true if interlaced */ |
668 int bottom_field; /* true if bottom field */ | 813 int bottom_field; /* true if bottom field */ |
669 int lossless; | 814 int lossless; |
670 int rgb; | 815 int rgb; |
671 int rct; /* pegasus reversible colorspace transform */ | 816 int rct; /* standard rct */ |
817 int pegasus_rct; /* pegasus reversible colorspace transform */ | |
672 int bits; /* bits per component */ | 818 int bits; /* bits per component */ |
673 | 819 |
674 int width, height; | 820 int width, height; |
675 int nb_components; | 821 int nb_components; |
676 int component_id[MAX_COMPONENTS]; | 822 int component_id[MAX_COMPONENTS]; |
832 int len, nb_components, i, width, height; | 978 int len, nb_components, i, width, height; |
833 | 979 |
834 /* XXX: verify len field validity */ | 980 /* XXX: verify len field validity */ |
835 len = get_bits(&s->gb, 16); | 981 len = get_bits(&s->gb, 16); |
836 s->bits= get_bits(&s->gb, 8); | 982 s->bits= get_bits(&s->gb, 8); |
837 if(s->rct) s->bits=9; | 983 |
984 if(s->pegasus_rct) s->bits=9; | |
985 if(s->bits==9 && !s->pegasus_rct) s->rct=1; //FIXME ugly | |
838 | 986 |
839 if (s->bits != 8 && !s->lossless){ | 987 if (s->bits != 8 && !s->lossless){ |
840 printf("only 8 bits/component accepted\n"); | 988 printf("only 8 bits/component accepted\n"); |
841 return -1; | 989 return -1; |
842 } | 990 } |
989 } | 1137 } |
990 } | 1138 } |
991 return 0; | 1139 return 0; |
992 } | 1140 } |
993 | 1141 |
994 static void decode_lossless(MJpegDecodeContext *s, int point_transform, int predictor){ | |
995 } | |
996 | |
997 static int mjpeg_decode_sos(MJpegDecodeContext *s) | 1142 static int mjpeg_decode_sos(MJpegDecodeContext *s) |
998 { | 1143 { |
999 int len, nb_components, i, j, n, h, v, ret, point_transform, predictor; | 1144 int len, nb_components, i, j, n, h, v, ret, point_transform, predictor; |
1000 int mb_width, mb_height, mb_x, mb_y, vmax, hmax, index, id; | 1145 int mb_width, mb_height, mb_x, mb_y, vmax, hmax, index, id; |
1001 int comp_index[4]; | 1146 int comp_index[4]; |
1115 s->restart_count = s->restart_interval; | 1260 s->restart_count = s->restart_interval; |
1116 | 1261 |
1117 for(i=0;i<3;i++) { | 1262 for(i=0;i<3;i++) { |
1118 int pred; | 1263 int pred; |
1119 | 1264 |
1120 PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); | |
1121 | |
1122 topleft[i]= top[i]; | 1265 topleft[i]= top[i]; |
1123 top[i]= buffer[mb_x][i]; | 1266 top[i]= buffer[mb_x][i]; |
1267 | |
1268 PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); | |
1124 | 1269 |
1125 left[i]= | 1270 left[i]= |
1126 buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform)); | 1271 buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, dc_index[i]) << point_transform)); |
1127 } | 1272 } |
1128 | 1273 |
1131 skip_bits(&s->gb, 16); /* skip RSTn */ | 1276 skip_bits(&s->gb, 16); /* skip RSTn */ |
1132 } | 1277 } |
1133 } | 1278 } |
1134 | 1279 |
1135 if(s->rct){ | 1280 if(s->rct){ |
1281 for(mb_x = 0; mb_x < mb_width; mb_x++) { | |
1282 ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200)>>2); | |
1283 ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1]; | |
1284 ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; | |
1285 } | |
1286 }else if(s->pegasus_rct){ | |
1136 for(mb_x = 0; mb_x < mb_width; mb_x++) { | 1287 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); | 1288 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]; | 1289 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]; | 1290 ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; |
1140 } | 1291 } |
1397 skip_bits(&s->gb, 16); /* unknwon always 0? */ | 1548 skip_bits(&s->gb, 16); /* unknwon always 0? */ |
1398 skip_bits(&s->gb, 16); /* unknwon always 0? */ | 1549 skip_bits(&s->gb, 16); /* unknwon always 0? */ |
1399 switch( get_bits(&s->gb, 8)){ | 1550 switch( get_bits(&s->gb, 8)){ |
1400 case 1: | 1551 case 1: |
1401 s->rgb= 1; | 1552 s->rgb= 1; |
1402 s->rct=0; | 1553 s->pegasus_rct=0; |
1403 break; | 1554 break; |
1404 case 2: | 1555 case 2: |
1405 s->rgb= 1; | 1556 s->rgb= 1; |
1406 s->rct=1; | 1557 s->pegasus_rct=1; |
1407 break; | 1558 break; |
1408 default: | 1559 default: |
1409 printf("unknown colorspace\n"); | 1560 printf("unknown colorspace\n"); |
1410 } | 1561 } |
1411 len -= 9; | 1562 len -= 9; |
1658 avctx->width = s->width; | 1809 avctx->width = s->width; |
1659 /* XXX: not complete test ! */ | 1810 /* XXX: not complete test ! */ |
1660 switch((s->h_count[0] << 4) | s->v_count[0]) { | 1811 switch((s->h_count[0] << 4) | s->v_count[0]) { |
1661 case 0x11: | 1812 case 0x11: |
1662 if(s->rgb){ | 1813 if(s->rgb){ |
1663 #ifdef WORDS_BIGENDIAN | |
1664 avctx->pix_fmt = PIX_FMT_ABGR32; | |
1665 #else | |
1666 avctx->pix_fmt = PIX_FMT_RGBA32; | 1814 avctx->pix_fmt = PIX_FMT_RGBA32; |
1667 #endif | |
1668 }else | 1815 }else |
1669 avctx->pix_fmt = PIX_FMT_YUV444P; | 1816 avctx->pix_fmt = PIX_FMT_YUV444P; |
1670 break; | 1817 break; |
1671 case 0x21: | 1818 case 0x21: |
1672 avctx->pix_fmt = PIX_FMT_YUV422P; | 1819 avctx->pix_fmt = PIX_FMT_YUV422P; |
1888 mjpeg_decode_end, | 2035 mjpeg_decode_end, |
1889 mjpegb_decode_frame, | 2036 mjpegb_decode_frame, |
1890 0, | 2037 0, |
1891 NULL | 2038 NULL |
1892 }; | 2039 }; |
2040 | |
2041 AVCodec ljpeg_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them | |
2042 "ljpeg", | |
2043 CODEC_TYPE_VIDEO, | |
2044 CODEC_ID_LJPEG, | |
2045 sizeof(MpegEncContext), | |
2046 MPV_encode_init, | |
2047 encode_picture_lossless, | |
2048 MPV_encode_end, | |
2049 }; |