1/* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19static int FUNC(frame_header)(CodedBitstreamContext *ctx, RWContext *rw, 20 JPEGRawFrameHeader *current) 21{ 22 int err, i; 23 24 HEADER("Frame Header"); 25 26 u(16, Lf, 8, 8 + 3 * JPEG_MAX_COMPONENTS); 27 28 u(8, P, 2, 16); 29 u(16, Y, 0, JPEG_MAX_HEIGHT); 30 u(16, X, 1, JPEG_MAX_WIDTH); 31 u(8, Nf, 1, JPEG_MAX_COMPONENTS); 32 33 for (i = 0; i < current->Nf; i++) { 34 us(8, C[i], i, 0, JPEG_MAX_COMPONENTS); 35 us(4, H[i], i, 1, 4); 36 us(4, V[i], i, 1, 4); 37 us(8, Tq[i], i, 0, 3); 38 } 39 40 return 0; 41} 42 43static int FUNC(quantisation_table)(CodedBitstreamContext *ctx, RWContext *rw, 44 JPEGRawQuantisationTable *current) 45{ 46 int err, i; 47 48 u(4, Pq, 0, 1); 49 u(4, Tq, 0, 3); 50 51 if (current->Pq) { 52 for (i = 0; i < 64; i++) 53 us(16, Q[i], i, 1, 255); 54 } else { 55 for (i = 0; i < 64; i++) 56 us(8, Q[i], i, 1, 255); 57 } 58 59 return 0; 60} 61 62static int FUNC(dqt)(CodedBitstreamContext *ctx, RWContext *rw, 63 JPEGRawQuantisationTableSpecification *current) 64{ 65 int err, i, n; 66 67 HEADER("Quantisation Tables"); 68 69 u(16, Lq, 2, 2 + 4 * 65); 70 n = current->Lq / 65; 71 72 for (i = 0; i < n; i++) 73 CHECK(FUNC(quantisation_table)(ctx, rw, ¤t->table[i])); 74 75 return 0; 76} 77 78static int FUNC(huffman_table)(CodedBitstreamContext *ctx, RWContext *rw, 79 JPEGRawHuffmanTable *current) 80{ 81 int err, i, j, ij; 82 83 u(4, Tc, 0, 1); 84 u(4, Th, 0, 3); 85 86 for (i = 0; i < 16; i++) 87 us(8, L[i], i, 0, 255); 88 89 ij = 0; 90 for (i = 0; i < 16; i++) { 91 for (j = 0; j < current->L[i]; j++) { 92 if (ij >= FF_ARRAY_ELEMS(current->V)) 93 return AVERROR_INVALIDDATA; 94 us(8, V[ij], ij, 0, 255); 95 ++ij; 96 } 97 } 98 99 return 0; 100} 101 102static int FUNC(dht)(CodedBitstreamContext *ctx, RWContext *rw, 103 JPEGRawHuffmanTableSpecification *current) 104{ 105 int err, i, j, n; 106 107 HEADER("Huffman Tables"); 108 109 u(16, Lh, 2, 2 + 8 * (1 + 16 + 256)); 110 111 n = 2; 112 for (i = 0; n < current->Lh; i++) { 113 if (i >= 8) 114 return AVERROR_INVALIDDATA; 115 116 CHECK(FUNC(huffman_table)(ctx, rw, ¤t->table[i])); 117 118 ++n; 119 for (j = 0; j < 16; j++) 120 n += 1 + current->table[i].L[j]; 121 } 122 123 return 0; 124} 125 126static int FUNC(scan_header)(CodedBitstreamContext *ctx, RWContext *rw, 127 JPEGRawScanHeader *current) 128{ 129 int err, j; 130 131 HEADER("Scan"); 132 133 u(16, Ls, 6, 6 + 2 * JPEG_MAX_COMPONENTS); 134 135 u(8, Ns, 1, 4); 136 for (j = 0; j < current->Ns; j++) { 137 us(8, Cs[j], j, 0, JPEG_MAX_COMPONENTS); 138 us(4, Td[j], j, 0, 3); 139 us(4, Ta[j], j, 0, 3); 140 } 141 142 u(8, Ss, 0, 63); 143 u(8, Se, 0, 63); 144 u(4, Ah, 0, 13); 145 u(4, Al, 0, 15); 146 147 return 0; 148} 149 150static int FUNC(application_data)(CodedBitstreamContext *ctx, RWContext *rw, 151 JPEGRawApplicationData *current) 152{ 153 int err, i; 154 155 HEADER("Application Data"); 156 157 u(16, Lp, 2, 65535); 158 159 if (current->Lp > 2) { 160#ifdef READ 161 current->Ap_ref = av_buffer_alloc(current->Lp - 2); 162 if (!current->Ap_ref) 163 return AVERROR(ENOMEM); 164 current->Ap = current->Ap_ref->data; 165#endif 166 167 for (i = 0; i < current->Lp - 2; i++) 168 us(8, Ap[i], i, 0, 255); 169 } 170 171 return 0; 172} 173 174static int FUNC(comment)(CodedBitstreamContext *ctx, RWContext *rw, 175 JPEGRawComment *current) 176{ 177 int err, i; 178 179 HEADER("Comment"); 180 181 u(16, Lc, 2, 65535); 182 183 if (current->Lc > 2) { 184#ifdef READ 185 current->Cm_ref = av_buffer_alloc(current->Lc - 2); 186 if (!current->Cm_ref) 187 return AVERROR(ENOMEM); 188 current->Cm = current->Cm_ref->data; 189#endif 190 191 for (i = 0; i < current->Lc - 2; i++) 192 us(8, Cm[i], i, 0, 255); 193 } 194 195 return 0; 196} 197