diff options
Diffstat (limited to 'apps/plugins/jpeg.c')
-rw-r--r-- | apps/plugins/jpeg.c | 151 |
1 files changed, 87 insertions, 64 deletions
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c index 637afcc131..ed21222653 100644 --- a/apps/plugins/jpeg.c +++ b/apps/plugins/jpeg.c | |||
@@ -606,6 +606,7 @@ struct jpeg | |||
606 | int y_mbl; /* y dimension of MBL */ | 606 | int y_mbl; /* y dimension of MBL */ |
607 | int blocks; /* blocks per MBL */ | 607 | int blocks; /* blocks per MBL */ |
608 | int restart_interval; /* number of MCUs between RSTm markers */ | 608 | int restart_interval; /* number of MCUs between RSTm markers */ |
609 | int store_pos[4]; /* for Y block ordering */ | ||
609 | 610 | ||
610 | unsigned char* p_entropy_data; | 611 | unsigned char* p_entropy_data; |
611 | unsigned char* p_entropy_end; | 612 | unsigned char* p_entropy_end; |
@@ -688,67 +689,11 @@ int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg) | |||
688 | p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4; | 689 | p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4; |
689 | p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F; | 690 | p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F; |
690 | p_jpeg->frameheader[i].quanttable_select = *p_src++; | 691 | p_jpeg->frameheader[i].quanttable_select = *p_src++; |
692 | if (p_jpeg->frameheader[i].horizontal_sampling > 2 | ||
693 | || p_jpeg->frameheader[i].vertical_sampling > 2) | ||
694 | return -3; /* Unsupported SOF0 subsampling */ | ||
691 | } | 695 | } |
692 | 696 | p_jpeg->blocks = n; | |
693 | /* assignments for the decoding of blocks */ | ||
694 | if (p_jpeg->frameheader[0].horizontal_sampling == 2 | ||
695 | && p_jpeg->frameheader[0].vertical_sampling == 1) | ||
696 | { /* 4:2:2 */ | ||
697 | p_jpeg->blocks = 4; | ||
698 | p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16; | ||
699 | p_jpeg->x_phys = p_jpeg->x_mbl * 16; | ||
700 | p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8; | ||
701 | p_jpeg->y_phys = p_jpeg->y_mbl * 8; | ||
702 | p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=2, V=3 */ | ||
703 | p_jpeg->mcu_membership[1] = 0; | ||
704 | p_jpeg->mcu_membership[2] = 2; | ||
705 | p_jpeg->mcu_membership[3] = 3; | ||
706 | p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */ | ||
707 | p_jpeg->tab_membership[1] = 0; | ||
708 | p_jpeg->tab_membership[2] = 1; | ||
709 | p_jpeg->tab_membership[3] = 1; | ||
710 | } | ||
711 | else if (p_jpeg->frameheader[0].horizontal_sampling == 2 | ||
712 | && p_jpeg->frameheader[0].vertical_sampling == 2) | ||
713 | { /* 4:2:0 */ | ||
714 | p_jpeg->blocks = 6; | ||
715 | p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16; | ||
716 | p_jpeg->x_phys = p_jpeg->x_mbl * 16; | ||
717 | p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16; | ||
718 | p_jpeg->y_phys = p_jpeg->y_mbl * 16; | ||
719 | p_jpeg->mcu_membership[0] = 0; | ||
720 | p_jpeg->mcu_membership[1] = 0; | ||
721 | p_jpeg->mcu_membership[2] = 0; | ||
722 | p_jpeg->mcu_membership[3] = 0; | ||
723 | p_jpeg->mcu_membership[4] = 2; | ||
724 | p_jpeg->mcu_membership[5] = 3; | ||
725 | p_jpeg->tab_membership[0] = 0; | ||
726 | p_jpeg->tab_membership[1] = 0; | ||
727 | p_jpeg->tab_membership[2] = 0; | ||
728 | p_jpeg->tab_membership[3] = 0; | ||
729 | p_jpeg->tab_membership[4] = 1; | ||
730 | p_jpeg->tab_membership[5] = 1; | ||
731 | } | ||
732 | else if (p_jpeg->frameheader[0].horizontal_sampling == 1 | ||
733 | && p_jpeg->frameheader[0].vertical_sampling == 1) | ||
734 | { /* 4:4:4 */ | ||
735 | p_jpeg->blocks = n; | ||
736 | p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8; | ||
737 | p_jpeg->x_phys = p_jpeg->x_mbl * 8; | ||
738 | p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8; | ||
739 | p_jpeg->y_phys = p_jpeg->y_mbl * 8; | ||
740 | p_jpeg->mcu_membership[0] = 0; | ||
741 | p_jpeg->mcu_membership[1] = 2; | ||
742 | p_jpeg->mcu_membership[2] = 3; | ||
743 | p_jpeg->tab_membership[0] = 0; | ||
744 | p_jpeg->tab_membership[1] = 1; | ||
745 | p_jpeg->tab_membership[2] = 1; | ||
746 | } | ||
747 | else | ||
748 | { | ||
749 | return(-3); /* Unsupported SOF0 subsampling */ | ||
750 | } | ||
751 | |||
752 | } | 697 | } |
753 | break; | 698 | break; |
754 | 699 | ||
@@ -1103,6 +1048,84 @@ void build_lut(struct jpeg* p_jpeg) | |||
1103 | p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i]; | 1048 | p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i]; |
1104 | p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i]; | 1049 | p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i]; |
1105 | } | 1050 | } |
1051 | |||
1052 | for (i=0; i<4; i++) | ||
1053 | p_jpeg->store_pos[i] = i; /* default ordering */ | ||
1054 | |||
1055 | /* assignments for the decoding of blocks */ | ||
1056 | if (p_jpeg->frameheader[0].horizontal_sampling == 2 | ||
1057 | && p_jpeg->frameheader[0].vertical_sampling == 1) | ||
1058 | { /* 4:2:2 */ | ||
1059 | p_jpeg->blocks = 4; | ||
1060 | p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16; | ||
1061 | p_jpeg->x_phys = p_jpeg->x_mbl * 16; | ||
1062 | p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8; | ||
1063 | p_jpeg->y_phys = p_jpeg->y_mbl * 8; | ||
1064 | p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=2, V=3 */ | ||
1065 | p_jpeg->mcu_membership[1] = 0; | ||
1066 | p_jpeg->mcu_membership[2] = 2; | ||
1067 | p_jpeg->mcu_membership[3] = 3; | ||
1068 | p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */ | ||
1069 | p_jpeg->tab_membership[1] = 0; | ||
1070 | p_jpeg->tab_membership[2] = 1; | ||
1071 | p_jpeg->tab_membership[3] = 1; | ||
1072 | } | ||
1073 | if (p_jpeg->frameheader[0].horizontal_sampling == 1 | ||
1074 | && p_jpeg->frameheader[0].vertical_sampling == 2) | ||
1075 | { /* 4:2:2 vertically subsampled */ | ||
1076 | p_jpeg->store_pos[1] = 2; /* block positions are mirrored */ | ||
1077 | p_jpeg->store_pos[2] = 1; | ||
1078 | p_jpeg->blocks = 4; | ||
1079 | p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8; | ||
1080 | p_jpeg->x_phys = p_jpeg->x_mbl * 8; | ||
1081 | p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16; | ||
1082 | p_jpeg->y_phys = p_jpeg->y_mbl * 16; | ||
1083 | p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=2, V=3 */ | ||
1084 | p_jpeg->mcu_membership[1] = 0; | ||
1085 | p_jpeg->mcu_membership[2] = 2; | ||
1086 | p_jpeg->mcu_membership[3] = 3; | ||
1087 | p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */ | ||
1088 | p_jpeg->tab_membership[1] = 0; | ||
1089 | p_jpeg->tab_membership[2] = 1; | ||
1090 | p_jpeg->tab_membership[3] = 1; | ||
1091 | } | ||
1092 | else if (p_jpeg->frameheader[0].horizontal_sampling == 2 | ||
1093 | && p_jpeg->frameheader[0].vertical_sampling == 2) | ||
1094 | { /* 4:2:0 */ | ||
1095 | p_jpeg->blocks = 6; | ||
1096 | p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16; | ||
1097 | p_jpeg->x_phys = p_jpeg->x_mbl * 16; | ||
1098 | p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16; | ||
1099 | p_jpeg->y_phys = p_jpeg->y_mbl * 16; | ||
1100 | p_jpeg->mcu_membership[0] = 0; | ||
1101 | p_jpeg->mcu_membership[1] = 0; | ||
1102 | p_jpeg->mcu_membership[2] = 0; | ||
1103 | p_jpeg->mcu_membership[3] = 0; | ||
1104 | p_jpeg->mcu_membership[4] = 2; | ||
1105 | p_jpeg->mcu_membership[5] = 3; | ||
1106 | p_jpeg->tab_membership[0] = 0; | ||
1107 | p_jpeg->tab_membership[1] = 0; | ||
1108 | p_jpeg->tab_membership[2] = 0; | ||
1109 | p_jpeg->tab_membership[3] = 0; | ||
1110 | p_jpeg->tab_membership[4] = 1; | ||
1111 | p_jpeg->tab_membership[5] = 1; | ||
1112 | } | ||
1113 | else if (p_jpeg->frameheader[0].horizontal_sampling == 1 | ||
1114 | && p_jpeg->frameheader[0].vertical_sampling == 1) | ||
1115 | { /* 4:4:4 */ | ||
1116 | /* don't overwrite p_jpeg->blocks */ | ||
1117 | p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8; | ||
1118 | p_jpeg->x_phys = p_jpeg->x_mbl * 8; | ||
1119 | p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8; | ||
1120 | p_jpeg->y_phys = p_jpeg->y_mbl * 8; | ||
1121 | p_jpeg->mcu_membership[0] = 0; | ||
1122 | p_jpeg->mcu_membership[1] = 2; | ||
1123 | p_jpeg->mcu_membership[2] = 3; | ||
1124 | p_jpeg->tab_membership[0] = 0; | ||
1125 | p_jpeg->tab_membership[1] = 1; | ||
1126 | p_jpeg->tab_membership[2] = 1; | ||
1127 | } | ||
1128 | |||
1106 | } | 1129 | } |
1107 | 1130 | ||
1108 | 1131 | ||
@@ -1333,10 +1356,10 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale, | |||
1333 | skip_mcu = (width/p_jpeg->x_mbl); | 1356 | skip_mcu = (width/p_jpeg->x_mbl); |
1334 | 1357 | ||
1335 | /* prepare offsets about where to store the different blocks */ | 1358 | /* prepare offsets about where to store the different blocks */ |
1336 | store_offs[0] = 0; | 1359 | store_offs[p_jpeg->store_pos[0]] = 0; |
1337 | store_offs[1] = 8 / downscale; /* to the right */ | 1360 | store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */ |
1338 | store_offs[2] = width * 8 / downscale; /* below */ | 1361 | store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */ |
1339 | store_offs[3] = store_offs[1] + store_offs[2]; /* right+below */ | 1362 | store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */ |
1340 | 1363 | ||
1341 | for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++) | 1364 | for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++) |
1342 | { | 1365 | { |