History

avcodec/jpeg2000dec: Add support for placeholder passes

See Rec. ITU-T T.814 | ISO/IEC 15444-15, Annex B.

Osamu Watanabe committed 2 years ago

Commit 48b14731 parent fe1b1964 files · +326 −118Browse files

Unified · Split

4 files
  1. libavcodec/jpeg2000.h +2 −0
  2. libavcodec/jpeg2000dec.c +277 −75
  3. libavcodec/jpeg2000dec.h +1 −1
  4. libavcodec/jpeg2000htdec.c +46 −42
libavcodec/jpeg2000.h+2−0
@@ -200,6 +200,8 @@ typedef struct Jpeg2000Cblk { · 199 unmodified lines
200 /* specific to HT code-blocks */200 /* specific to HT code-blocks */
201 int zbp;201 int zbp;
202 int pass_lengths[2];202 int pass_lengths[2];
203 uint8_t modes; // copy of SPcod/SPcoc field to parse HT-MIXED mode
204 uint8_t ht_plhd; // are we looking for HT placeholder passes?
203} Jpeg2000Cblk; // code block205} Jpeg2000Cblk; // code block
204 206
205typedef struct Jpeg2000Prec {207typedef struct Jpeg2000Prec {
libavcodec/jpeg2000dec.c+277−75
@@ -54,6 +54,15 @@ · 53 unmodified lines
54#define HAD_COC 0x0154#define HAD_COC 0x01
55#define HAD_QCC 0x0255#define HAD_QCC 0x02
56 56
57// Values of flag for placeholder passes
58enum HT_PLHD_STATUS {
59 HT_PLHD_OFF,
60 HT_PLHD_ON
61};
62
63#define HT_MIXED 0x80 // bit 7 of SPcod/SPcoc
64
65
57/* get_bits functions for JPEG2000 packet bitstream66/* get_bits functions for JPEG2000 packet bitstream
58 * It is a get_bit function with a bit-stuffing routine. If the value of the67 * It is a get_bit function with a bit-stuffing routine. If the value of the
59 * byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB.68 * byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB.
@@ -1160,100 +1169,293 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, · 1100 unmodified lines
1160 int incl, newpasses, llen;1169 int incl, newpasses, llen;
1161 void *tmp;1170 void *tmp;
1162 1171
1163 if (cblk->npasses)1172 if (!cblk->incl) {
1164 incl = get_bits(s, 1);1173 incl = 0;
1165 else1174 cblk->modes = codsty->cblk_style;
1175 if (cblk->modes >= JPEG2000_CTSY_HTJ2K_F)
1176 cblk->ht_plhd = HT_PLHD_ON;
1177 if (layno > 0)
1178 incl = tag_tree_decode(s, prec->cblkincl + cblkno, 0 + 1) == 0;
1166 incl = tag_tree_decode(s, prec->cblkincl + cblkno, layno + 1) == layno;1179 incl = tag_tree_decode(s, prec->cblkincl + cblkno, layno + 1) == layno;
1167 if (!incl)
1168 continue;
1169 else if (incl < 0)
1170 return incl;
1171
1172 if (!cblk->npasses) {
1173 int zbp = tag_tree_decode(s, prec->zerobits + cblkno, 100);
1174 int v = expn[bandno] + numgbits - 1 - zbp;
1175 1180
1176 if (v < 0 || v > 30) {1181 if (incl) {
1177 av_log(s->avctx, AV_LOG_ERROR,1182 int zbp = tag_tree_decode(s, prec->zerobits + cblkno, 100);
1178 "nonzerobits %d invalid or unsupported\n", v);1183 int v = expn[bandno] + numgbits - 1 - (zbp - tile->comp->roi_shift);
1179 return AVERROR_INVALIDDATA;1184 if (v < 0 || v > 30) {
1185 av_log(s->avctx, AV_LOG_ERROR,
1186 "nonzerobits %d invalid or unsupported\n", v);
1187 return AVERROR_INVALIDDATA;
1188 }
1189 cblk->incl = 1;
1190 cblk->nonzerobits = v;
1191 cblk->zbp = zbp;
1192 cblk->lblock = 3;
1180 }1193 }
1181 cblk->zbp = zbp;1194 } else {
1182 cblk->nonzerobits = v;1195 incl = get_bits(s, 1);
1183 }
1184 if ((newpasses = getnpasses(s)) < 0)
1185 return newpasses;
1186 av_assert2(newpasses > 0);
1187 if (cblk->npasses + newpasses >= JPEG2000_MAX_PASSES) {
1188 avpriv_request_sample(s->avctx, "Too many passes");
1189 return AVERROR_PATCHWELCOME;
1190 }
1191 if ((llen = getlblockinc(s)) < 0)
1192 return llen;
1193 if (cblk->lblock + llen + av_log2(newpasses) > 16) {
1194 avpriv_request_sample(s->avctx,
1195 "Block with length beyond 16 bits");
1196 return AVERROR_PATCHWELCOME;
1197 }1196 }
1198 1197
1199 cblk->lblock += llen;1198 if (incl) {
1200 1199 uint8_t bypass_term_threshold = 0;
1201 cblk->nb_lengthinc = 0;1200 uint8_t bits_to_read = 0;
1202 cblk->nb_terminationsinc = 0;1201 uint32_t segment_bytes = 0;
1203 av_free(cblk->lengthinc);1202 int32_t segment_passes = 0;
1204 cblk->lengthinc = av_calloc(newpasses, sizeof(*cblk->lengthinc));1203 uint8_t next_segment_passes = 0;
1205 if (!cblk->lengthinc)1204 int32_t href_passes, pass_bound;
1206 return AVERROR(ENOMEM);1205 uint32_t tmp_length = 0;
1207 tmp = av_realloc_array(cblk->data_start, cblk->nb_terminations + newpasses + 1, sizeof(*cblk->data_start));1206 int32_t newpasses_copy, npasses_copy;
1208 if (!tmp)1207
1209 return AVERROR(ENOMEM);1208 if ((newpasses = getnpasses(s)) <= 0)
1210 cblk->data_start = tmp;1209 return newpasses;
1211 do {1210 if (cblk->npasses + newpasses >= JPEG2000_MAX_PASSES) {
1212 int newpasses1 = 0;1211 avpriv_request_sample(s->avctx, "Too many passes");
1212 return AVERROR_PATCHWELCOME;
1213 }
1214 if ((llen = getlblockinc(s)) < 0)
1215 return llen;
1216 if (cblk->lblock + llen + av_log2(newpasses) > 16) {
1217 avpriv_request_sample(s->avctx,
1218 "Block with length beyond 16 bits");
1219 return AVERROR_PATCHWELCOME;
1220 }
1221 cblk->nb_lengthinc = 0;
1222 cblk->nb_terminationsinc = 0;
1223 av_free(cblk->lengthinc);
1224 cblk->lengthinc = av_calloc(newpasses, sizeof(*cblk->lengthinc));
1225 if (!cblk->lengthinc)
1226 return AVERROR(ENOMEM);
1227 tmp = av_realloc_array(cblk->data_start, cblk->nb_terminations + newpasses + 1,
1228 sizeof(*cblk->data_start));
1229 if (!tmp)
1230 return AVERROR(ENOMEM);
1231 cblk->data_start = tmp;
1232 cblk->lblock += llen;
1233
1234 // Count number of necessary terminations for non HT code block
1235 newpasses_copy = newpasses;
1236 npasses_copy = cblk->npasses;
1237 if (!(cblk->modes & JPEG2000_CTSY_HTJ2K_F)) {
1238 do {
1239 int newpasses1 = 0;
1240
1241 while (newpasses1 < newpasses_copy) {
1242 newpasses1++;
1243 if (needs_termination(codsty->cblk_style, npasses_copy + newpasses1 - 1)) {
1244 cblk->nb_terminationsinc++;
1245 break;
1246 }
1247 }
1248 npasses_copy += newpasses1;
1249 newpasses_copy -= newpasses1;
1250 } while (newpasses_copy);
1251 }
1213 1252
1214 while (newpasses1 < newpasses) {1253 if (cblk->ht_plhd) {
1215 newpasses1 ++;1254 href_passes = (cblk->npasses + newpasses - 1) % 3;
1216 if (needs_termination(codsty->cblk_style, cblk->npasses + newpasses1 - 1)) {1255 segment_passes = newpasses - href_passes;
1217 cblk->nb_terminationsinc ++;1256 pass_bound = 2;
1218 break;1257 bits_to_read = cblk->lblock;
1258 if (segment_passes < 1) {
1259 // No possible HT Cleanup pass here; may have placeholder passes
1260 // or an original J2K block bit-stream (in MIXED mode).
1261 segment_passes = newpasses;
1262 while (pass_bound <= segment_passes) {
1263 bits_to_read++;
1264 pass_bound += pass_bound;
1265 }
1266 segment_bytes = get_bits(s, bits_to_read);
1267 if (segment_bytes) {
1268 if (cblk->modes & HT_MIXED) {
1269 cblk->ht_plhd = HT_PLHD_OFF;
1270 cblk->modes &= (uint8_t) (~(JPEG2000_CTSY_HTJ2K_F));
1271 }
1272 else {
1273 av_log(s->avctx, AV_LOG_WARNING, "Length information for a HT-codeblock is invalid\n");
1274 }
1275 }
1276 } else {
1277 while (pass_bound <= segment_passes) {
1278 bits_to_read++;
1279 pass_bound += pass_bound;
1280 }
1281 segment_bytes = get_bits(s, bits_to_read);
1282 if (segment_bytes) {
1283 // No more placeholder passes
1284 if (!(cblk->modes & HT_MIXED)) {
1285 // Must be the first HT Cleanup pass
1286 if (segment_bytes < 2)
1287 av_log(s->avctx, AV_LOG_WARNING, "Length information for a HT-codeblock is invalid\n");
1288 next_segment_passes = 2;
1289 cblk->ht_plhd = HT_PLHD_OFF;
1290 // Write length information for HT CleanUp segment
1291 cblk->pass_lengths[0] = segment_bytes;
1292 } else if (cblk->lblock > 3 && segment_bytes > 1
1293 && (segment_bytes >> (bits_to_read - 1)) == 0) {
1294 // Must be the first HT Cleanup pass, since length MSB is 0
1295 next_segment_passes = 2;
1296 cblk->ht_plhd = HT_PLHD_OFF;
1297 // Write length information for HT CleanUp segment
1298 cblk->pass_lengths[0] = segment_bytes;
1299 } else {
1300 // Must have an original (non-HT) block coding pass
1301 cblk->modes &= (uint8_t) (~(JPEG2000_CTSY_HTJ2K_F));
1302 cblk->ht_plhd = HT_PLHD_OFF;
1303 segment_passes = newpasses;
1304 while (pass_bound <= segment_passes) {
1305 bits_to_read++;
1306 pass_bound += pass_bound;
1307 segment_bytes <<= 1;
1308 segment_bytes += get_bits(s, 1);
1309 }
1310 }
1311 } else {
1312 // Probably parsing placeholder passes, but we need to read an
1313 // extra length bit to verify this, since prior to the first
1314 // HT Cleanup pass, the number of length bits read for a
1315 // contributing code-block is dependent on the number of passes
1316 // being included, as if it were a non-HT code-block.
1317 segment_passes = newpasses;
1318 if (pass_bound <= segment_passes) {
1319 while (1) {
1320 bits_to_read++;
1321 pass_bound += pass_bound;
1322 segment_bytes <<= 1;
1323 segment_bytes += get_bits(s, 1);
1324 if (pass_bound > segment_passes)
1325 break;
1326 }
1327 if (segment_bytes) {
1328 if (cblk->modes & HT_MIXED) {
1329 cblk->modes &= (uint8_t) (~(JPEG2000_CTSY_HTJ2K_F));
1330 cblk->ht_plhd = HT_PLHD_OFF;
1331 } else {
1332 av_log(s->avctx, AV_LOG_WARNING, "Length information for a HT-codeblock is invalid\n");
1333 }
1334 }
1335 }
1336 }
1337 }
1338 } else if (cblk->modes & JPEG2000_CTSY_HTJ2K_F) {
1339 // Quality layer commences with a non-initial HT coding pass
1340 if(bits_to_read != 0)
1341 av_log(s->avctx, AV_LOG_WARNING, "Length information for a HT-codeblock is invalid\n");
1342 segment_passes = cblk->npasses % 3;
1343 if (segment_passes == 0) {
1344 // newpasses is a HT Cleanup pass; next segment has refinement passes
1345 segment_passes = 1;
1346 next_segment_passes = 2;
1347 if (segment_bytes == 1)
1348 av_log(s->avctx, AV_LOG_WARNING, "Length information for a HT-codeblock is invalid\n");
1349 } else {
1350 // newpasses = 1 means npasses is HT SigProp; 2 means newpasses is
1351 // HT MagRef pass
1352 segment_passes = newpasses > 1 ? 3 - segment_passes : 1;
1353 next_segment_passes = 1;
1354 bits_to_read = av_log2(segment_passes);
1355 }
1356 bits_to_read = (uint8_t) (bits_to_read + cblk->lblock);
1357 segment_bytes = get_bits(s, bits_to_read);
1358 // Write length information for HT Refinment segment
1359 cblk->pass_lengths[1] += segment_bytes;
1360 } else if (!(cblk->modes & (JPEG2000_CBLK_TERMALL | JPEG2000_CBLK_BYPASS))) {
1361 // Common case for non-HT code-blocks; we have only one segment
1362 bits_to_read = (uint8_t) cblk->lblock + av_log2((uint8_t) newpasses);
1363 segment_bytes = get_bits(s, bits_to_read);
1364 segment_passes = newpasses;
1365 } else if (cblk->modes & JPEG2000_CBLK_TERMALL) {
1366 // RESTART MODE
1367 bits_to_read = cblk->lblock;
1368 segment_bytes = get_bits(s, bits_to_read);
1369 segment_passes = 1;
1370 next_segment_passes = 1;
1371 } else {
1372 // BYPASS MODE
1373 bypass_term_threshold = 10;
1374 if(bits_to_read != 0)
1375 av_log(s->avctx, AV_LOG_WARNING, "Length information for a codeblock is invalid\n");
1376 if (cblk->npasses < bypass_term_threshold) {
1377 // May have from 1 to 10 uninterrupted passes before 1st RAW SigProp
1378 segment_passes = bypass_term_threshold - cblk->npasses;
1379 if (segment_passes > newpasses)
1380 segment_passes = newpasses;
1381 while ((2 << bits_to_read) <= segment_passes)
1382 bits_to_read++;
1383 next_segment_passes = 2;
1384 } else if ((cblk->npasses - bypass_term_threshold) % 3 < 2) {
1385 // 0 means newpasses is a RAW SigProp; 1 means newpasses is a RAW MagRef pass
1386 segment_passes = newpasses > 1 ? 2 - (cblk->npasses - bypass_term_threshold) % 3 : 1;
1387 bits_to_read = av_log2(segment_passes);
1388 next_segment_passes = 1;
1389 } else {
1390 // newpasses is an isolated Cleanup pass that precedes a RAW SigProp pass
1391 segment_passes = 1;
1392 next_segment_passes = 2;
1219 }1393 }
1394 bits_to_read = (uint8_t) (bits_to_read + cblk->lblock);
1395 segment_bytes = get_bits(s, bits_to_read);
1220 }1396 }
1221 1397 // Update cblk->npasses and write length information
1222 if (newpasses > 1 && (codsty->cblk_style & JPEG2000_CTSY_HTJ2K_F)) {1398 cblk->npasses = (uint8_t) (cblk->npasses + segment_passes);
1223 // Retrieve pass lengths for each pass1399 cblk->lengthinc[cblk->nb_lengthinc++] = segment_bytes;
1224 int href_passes = (cblk->npasses + newpasses - 1) % 3;1400
1225 int eb = av_log2(newpasses - href_passes);1401 if ((cblk->modes & JPEG2000_CTSY_HTJ2K_F) && cblk->ht_plhd == HT_PLHD_OFF) {
1226 int extra_bit = newpasses > 2 ? 1 : 0;1402 newpasses -= (uint8_t) segment_passes;
1227 if ((ret = get_bits(s, llen + eb + 3)) < 0)1403 while (newpasses > 0) {
1228 return ret;1404 segment_passes = newpasses > 1 ? next_segment_passes : 1;
1229 cblk->pass_lengths[0] = ret;1405 next_segment_passes = (uint8_t) (3 - next_segment_passes);
1230 if ((ret = get_bits(s, llen + 3 + extra_bit)) < 0)1406 bits_to_read = (uint8_t) (cblk->lblock + av_log2(segment_passes));
1231 return ret;1407 segment_bytes = get_bits(s, bits_to_read);
1232 cblk->pass_lengths[1] = ret;1408 newpasses -= (uint8_t) (segment_passes);
1233 ret = cblk->pass_lengths[0] + cblk->pass_lengths[1];1409 // This is a FAST Refinement pass
1410 // Write length information for HT Refinement segment
1411 cblk->pass_lengths[1] += segment_bytes;
1412 // Update cblk->npasses and write length information
1413 cblk->npasses = (uint8_t) (cblk->npasses + segment_passes);
1414 cblk->lengthinc[cblk->nb_lengthinc++] = segment_bytes;
1415 }
1234 } else {1416 } else {
1235 if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0)1417 newpasses -= (uint8_t) (segment_passes);
1236 return ret;1418 while (newpasses > 0) {
1237 cblk->pass_lengths[0] = ret;1419 if (bypass_term_threshold != 0) {
1420 segment_passes = newpasses > 1 ? next_segment_passes : 1;
1421 next_segment_passes = (uint8_t) (3 - next_segment_passes);
1422 bits_to_read = (uint8_t) (cblk->lblock + av_log2(segment_passes));
1423 } else {
1424 if ((cblk->modes & JPEG2000_CBLK_TERMALL) == 0)
1425 av_log(s->avctx, AV_LOG_WARNING, "Corrupted packet header is found.\n");
1426 segment_passes = 1;
1427 bits_to_read = cblk->lblock;
1428 }
1429 segment_bytes = get_bits(s, bits_to_read);
1430 newpasses -= (uint8_t) (segment_passes);
1431
1432 // Update cblk->npasses and write length information
1433 cblk->npasses = (uint8_t) (cblk->npasses + segment_passes);
1434 cblk->lengthinc[cblk->nb_lengthinc++] = segment_bytes;
1435 }
1238 }1436 }
1239 if (ret > cblk->data_allocated) {1437
1240 size_t new_size = FFMAX(2*cblk->data_allocated, ret);1438 for (int i = 0; i < cblk->nb_lengthinc; ++i)
1439 tmp_length = (tmp_length < cblk->lengthinc[i]) ? cblk->lengthinc[i] : tmp_length;
1440
1441 if (tmp_length > cblk->data_allocated) {
1442 size_t new_size = FFMAX(2 * cblk->data_allocated, tmp_length);
1241 void *new = av_realloc(cblk->data, new_size);1443 void *new = av_realloc(cblk->data, new_size);
1242 if (new) {1444 if (new) {
1243 cblk->data = new;1445 cblk->data = new;
1244 cblk->data_allocated = new_size;1446 cblk->data_allocated = new_size;
1245 }1447 }
1246 }1448 }
1247 if (ret > cblk->data_allocated) {1449 if (tmp_length > cblk->data_allocated) {
1248 avpriv_request_sample(s->avctx,1450 avpriv_request_sample(s->avctx,
1249 "Block with lengthinc greater than %"SIZE_SPECIFIER"",1451 "Block with lengthinc greater than %"SIZE_SPECIFIER"",
1250 cblk->data_allocated);1452 cblk->data_allocated);
1251 return AVERROR_PATCHWELCOME;1453 return AVERROR_PATCHWELCOME;
1252 }1454 }
1253 cblk->lengthinc[cblk->nb_lengthinc++] = ret;1455 } else {
1254 cblk->npasses += newpasses1;1456 // This codeblock has no contribution to the current packet
1255 newpasses -= newpasses1;1457 continue;
1256 } while(newpasses);1458 }
1257 }1459 }
1258 }1460 }
1259 jpeg2000_flush(s);1461 jpeg2000_flush(s);
@@ -1788,7 +1990,7 @@ static int decode_cblk(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *cod · 528 unmodified lines
1788 Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,1990 Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,
1789 int width, int height, int bandpos, uint8_t roi_shift)1991 int width, int height, int bandpos, uint8_t roi_shift)
1790{1992{
1791 int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1 + roi_shift;1993 int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1;
1792 int pass_cnt = 0;1994 int pass_cnt = 0;
1793 int vert_causal_ctx_csty_symbol = codsty->cblk_style & JPEG2000_CBLK_VSC;1995 int vert_causal_ctx_csty_symbol = codsty->cblk_style & JPEG2000_CBLK_VSC;
1794 int term_cnt = 0;1996 int term_cnt = 0;
@@ -2028,7 +2230,7 @@ static inline int tile_codeblocks(const Jpeg2000DecoderContext *s, Jpeg2000Tile · 233 unmodified lines
2028 2230
2029 Jpeg2000Cblk *cblk = prec->cblk + cblkno;2231 Jpeg2000Cblk *cblk = prec->cblk + cblkno;
2030 2232
2031 if (codsty->cblk_style & JPEG2000_CTSY_HTJ2K_F)2233 if (cblk->modes & JPEG2000_CTSY_HTJ2K_F)
2032 ret = ff_jpeg2000_decode_htj2k(s, codsty, &t1, cblk,2234 ret = ff_jpeg2000_decode_htj2k(s, codsty, &t1, cblk,
2033 cblk->coord[0][1] - cblk->coord[0][0],2235 cblk->coord[0][1] - cblk->coord[0][0],
2034 cblk->coord[1][1] - cblk->coord[1][0],2236 cblk->coord[1][1] - cblk->coord[1][0],
libavcodec/jpeg2000dec.h+1−1
@@ -117,7 +117,7 @@ typedef struct Jpeg2000DecoderContext { · 116 unmodified lines
117 uint8_t Ccap15_b12; // RGNFREE(= 0) or RGN(= 1)?117 uint8_t Ccap15_b12; // RGNFREE(= 0) or RGN(= 1)?
118 uint8_t Ccap15_b11; // HOMOGENEOUS(= 0) or HETEROGENEOUS(= 1) ?118 uint8_t Ccap15_b11; // HOMOGENEOUS(= 0) or HETEROGENEOUS(= 1) ?
119 uint8_t Ccap15_b05; // HTREV(= 0) or HTIRV(= 1) ?119 uint8_t Ccap15_b05; // HTREV(= 0) or HTIRV(= 1) ?
120 uint8_t HT_B; // MAGB value120 uint8_t HT_B; // The parameter B for MAGBp value (see Table 4 in the Rec. ITU-T T.814 | ISO/IEC 15444-15)
121 121
122 /*options parameters*/122 /*options parameters*/
123 int reduction_factor;123 int reduction_factor;
libavcodec/jpeg2000htdec.c+46−42
@@ -1032,25 +1032,31 @@ static void jpeg2000_calc_mbr(uint8_t *mbr, const uint16_t i, const uint16_t j, · 1031 unmodified lines
1032static void jpeg2000_process_stripes_block(StateVars *sig_prop, int i_s, int j_s,1032static void jpeg2000_process_stripes_block(StateVars *sig_prop, int i_s, int j_s,
1033 int width, int height, int stride, int pLSB,1033 int width, int height, int stride, int pLSB,
1034 int32_t *sample_buf, uint8_t *block_states,1034 int32_t *sample_buf, uint8_t *block_states,
1035 uint8_t *magref_segment, uint32_t magref_length)1035 uint8_t *magref_segment, uint32_t magref_length,
1036 uint8_t is_causal)
1036{1037{
1037 for (int j = j_s; j < j_s + width; j++) {1038 for (int j = j_s; j < j_s + width; j++) {
1038 uint32_t mbr_info = 0;1039 uint32_t mbr_info = 0;
1039 for (int i = i_s; i < i_s + height; i++) {1040 for (int i = i_s; i < i_s + height; i++) {
1040 int modify_state, cond;1041 int modify_state;
1041 uint8_t bit;1042 uint8_t bit;
1042 uint8_t causal_cond = i != (i_s + height - 1);1043 uint8_t causal_cond = (is_causal == 0) || (i != (i_s + height - 1));
1043 int32_t *sp = &sample_buf[j + (i * (stride))];1044 int32_t *sp = &sample_buf[j + (i * (stride))];
1044 uint8_t mbr = 0;1045 uint8_t mbr = 0;
1045 1046
1046 if (jpeg2000_get_state(i, j, stride - 2, HT_SHIFT_SIGMA, block_states) == 0)1047 if (jpeg2000_get_state(i, j, stride, HT_SHIFT_SIGMA, block_states) == 0)
1047 jpeg2000_calc_mbr(&mbr, i, j, mbr_info & 0x1EF, causal_cond, block_states, stride);1048 jpeg2000_calc_mbr(&mbr, i, j, mbr_info & 0x1EF, causal_cond, block_states, stride);
1048 mbr_info >>= 3;1049 mbr_info >>= 3;
1049 cond = mbr != 0;1050
1050 bit = jpeg2000_peek_bit(sig_prop, magref_segment, magref_length);1051 modify_state = block_states[(i + 1) * stride + (j + 1)];
1051 *sp |= (bit * cond) << pLSB;1052 modify_state |= 1 << HT_SHIFT_SCAN;
1052 sig_prop->bits -= cond;1053 if (mbr != 0) {
1053 modify_state = (((1 << HT_SHIFT_REF_IND) | (1 << HT_SHIFT_REF)) * cond) | 1 << HT_SHIFT_SCAN;1054 modify_state |= 1 << HT_SHIFT_REF_IND;
1055 bit = jpeg2000_peek_bit(sig_prop, magref_segment, magref_length);
1056 modify_state |= bit << HT_SHIFT_REF;
1057 *sp |= bit << pLSB;
1058 *sp |= bit << (pLSB - 1); // Add 0.5 (reconstruction parameter = 1/2)
1059 }
1054 jpeg2000_modify_state(i, j, stride, modify_state, block_states);1060 jpeg2000_modify_state(i, j, stride, modify_state, block_states);
1055 }1061 }
1056 }1062 }
@@ -1074,6 +1080,7 @@ static void jpeg2000_decode_sigprop_segment(Jpeg2000Cblk *cblk, uint16_t width, · 17 unmodified lines
1074 1080
1075 int last_width;1081 int last_width;
1076 uint16_t i = 0, j = 0;1082 uint16_t i = 0, j = 0;
1083 uint8_t is_causal = cblk->modes & JPEG2000_CBLK_VSC;
1077 1084
1078 jpeg2000_init_zero(&sp_dec);1085 jpeg2000_init_zero(&sp_dec);
1079 1086
@@ -1082,14 +1089,14 @@ static void jpeg2000_decode_sigprop_segment(Jpeg2000Cblk *cblk, uint16_t width, · 2 unmodified lines
1082 for (int n2 = 0; n2 < num_h_stripe; n2++) {1089 for (int n2 = 0; n2 < num_h_stripe; n2++) {
1083 jpeg2000_process_stripes_block(&sp_dec, i, j, b_width, b_height, stride,1090 jpeg2000_process_stripes_block(&sp_dec, i, j, b_width, b_height, stride,
1084 pLSB, sample_buf, block_states, magref_segment,1091 pLSB, sample_buf, block_states, magref_segment,
1085 magref_length);1092 magref_length, is_causal);
1086 j += 4;1093 j += 4;
1087 }1094 }
1088 last_width = width % 4;1095 last_width = width % 4;
1089 if (last_width)1096 if (last_width)
1090 jpeg2000_process_stripes_block(&sp_dec, i, j, last_width, b_height, stride,1097 jpeg2000_process_stripes_block(&sp_dec, i, j, last_width, b_height, stride,
1091 pLSB, sample_buf, block_states, magref_segment,1098 pLSB, sample_buf, block_states, magref_segment,
1092 magref_length);1099 magref_length, is_causal);
1093 i += 4;1100 i += 4;
1094 }1101 }
1095 1102
@@ -1099,20 +1106,20 @@ static void jpeg2000_decode_sigprop_segment(Jpeg2000Cblk *cblk, uint16_t width, · 3 unmodified lines
1099 for (int n2 = 0; n2 < num_h_stripe; n2++) {1106 for (int n2 = 0; n2 < num_h_stripe; n2++) {
1100 jpeg2000_process_stripes_block(&sp_dec, i, j, b_width, b_height, stride,1107 jpeg2000_process_stripes_block(&sp_dec, i, j, b_width, b_height, stride,
1101 pLSB, sample_buf, block_states, magref_segment,1108 pLSB, sample_buf, block_states, magref_segment,
1102 magref_length);1109 magref_length, is_causal);
1103 j += 4;1110 j += 4;
1104 }1111 }
1105 last_width = width % 4;1112 last_width = width % 4;
1106 if (last_width)1113 if (last_width)
1107 jpeg2000_process_stripes_block(&sp_dec, i, j, last_width, b_height, stride,1114 jpeg2000_process_stripes_block(&sp_dec, i, j, last_width, b_height, stride,
1108 pLSB, sample_buf, block_states, magref_segment,1115 pLSB, sample_buf, block_states, magref_segment,
1109 magref_length);1116 magref_length, is_causal);
1110}1117}
1111 1118
1112/**1119/**
1113 * See procedure decodeSigPropMag at Rec. ITU-T T.814, 7.5.1120 * See procedure decodeSigPropMag at Rec. ITU-T T.814, 7.5.
1114*/1121*/
1115static int1122static void
1116jpeg2000_decode_magref_segment( uint16_t width, uint16_t block_height, const int stride,1123jpeg2000_decode_magref_segment( uint16_t width, uint16_t block_height, const int stride,
1117 uint8_t *magref_segment,uint32_t magref_length,1124 uint8_t *magref_segment,uint32_t magref_length,
1118 uint8_t pLSB, int32_t *sample_buf, uint8_t *block_states)1125 uint8_t pLSB, int32_t *sample_buf, uint8_t *block_states)
@@ -1152,15 +1159,14 @@ jpeg2000_decode_magref_segment( uint16_t width, uint16_t block_height, const int · 33 unmodified lines
1152 }1159 }
1153 }1160 }
1154 }1161 }
1155 return 1;
1156}1162}
1157 1163
1158 1164
1159int1165int
1160ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,1166ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,
1161 int width, int height, int magp, uint8_t roi_shift)1167 int width, int height, int M_b, uint8_t roi_shift)
1162{1168{
1163 uint8_t p0 = 0; // Number of placeholder passes1169 uint8_t p0 = 0; // 3 * p0 = Number of placeholder passes
1164 uint32_t Lcup; // Length of HT cleanup segment1170 uint32_t Lcup; // Length of HT cleanup segment
1165 uint32_t Lref; // Length of Refinement segment1171 uint32_t Lref; // Length of Refinement segment
1166 uint32_t Scup; // HT cleanup segment suffix length1172 uint32_t Scup; // HT cleanup segment suffix length
@@ -1174,7 +1180,7 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c · 7 unmodified lines
1174 1180
1175 int z_blk; // Number of ht coding pass1181 int z_blk; // Number of ht coding pass
1176 1182
1177 uint8_t empty_passes;1183 uint8_t num_plhd_passes; // Number of placeholder passes
1178 1184
1179 StateVars mag_sgn; // Magnitude and Sign1185 StateVars mag_sgn; // Magnitude and Sign
1180 StateVars mel; // Adaptive run-length coding1186 StateVars mel; // Adaptive run-length coding
@@ -1190,8 +1196,9 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c · 9 unmodified lines
1190 uint8_t *block_states = NULL;1196 uint8_t *block_states = NULL;
1191 1197
1192 int32_t n, val; // Post-processing1198 int32_t n, val; // Post-processing
1199 const uint32_t mask = UINT32_MAX >> (M_b + 1); // bit mask for ROI detection
1193 1200
1194 int32_t M_b = magp;1201 uint8_t num_rempass;
1195 1202
1196 const int quad_buf_width = width + 4;1203 const int quad_buf_width = width + 4;
1197 const int quad_buf_height = height + 4;1204 const int quad_buf_height = height + 4;
@@ -1201,22 +1208,17 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c · 3 unmodified lines
1201 av_assert0(width * height <= 4096);1208 av_assert0(width * height <= 4096);
1202 av_assert0(width * height > 0);1209 av_assert0(width * height > 0);
1203 1210
1204 if (roi_shift)
1205 avpriv_report_missing_feature(s->avctx, "ROI shift");
1206
1207 memset(t1->data, 0, t1->stride * height * sizeof(*t1->data));1211 memset(t1->data, 0, t1->stride * height * sizeof(*t1->data));
1208 memset(t1->flags, 0, t1->stride * (height + 2) * sizeof(*t1->flags));1212 memset(t1->flags, 0, t1->stride * (height + 2) * sizeof(*t1->flags));
1209 1213
1210 if (cblk->npasses == 0)1214 if (cblk->npasses == 0)
1211 return 0;1215 return 0;
1212 1216
1213 if (cblk->npasses > 3)1217 num_rempass = cblk->npasses % 3; // Number of remainder passes
1214 p0 = 0;1218 num_plhd_passes = num_rempass ? cblk->npasses - num_rempass : cblk->npasses - 3;
1215 else if (cblk->length == 0)1219 av_assert0(num_plhd_passes % 3 == 0);
1216 p0 = 1;1220 p0 = num_plhd_passes / 3;
1217 1221 z_blk = cblk->npasses - num_plhd_passes;
1218 empty_passes = p0 * 3;
1219 z_blk = cblk->npasses - empty_passes;
1220 1222
1221 if (z_blk <= 0)1223 if (z_blk <= 0)
1222 return 0; // No passes within this set, continue1224 return 0; // No passes within this set, continue
@@ -1232,6 +1234,7 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c · 9 unmodified lines
1232 Dcup = cblk->data;1234 Dcup = cblk->data;
1233 Dref = cblk->data + Lcup; // Dref comes after the refinement segment1235 Dref = cblk->data + Lcup; // Dref comes after the refinement segment
1234 S_blk = p0 + cblk->zbp;1236 S_blk = p0 + cblk->zbp;
1237 cblk->zbp = S_blk - 1;
1235 pLSB = 30 - S_blk;1238 pLSB = 30 - S_blk;
1236 1239
1237 Scup = (Dcup[Lcup - 1] << 4) + (Dcup[Lcup - 2] & 0x0F);1240 Scup = (Dcup[Lcup - 1] << 4) + (Dcup[Lcup - 2] & 0x0F);
@@ -1277,31 +1280,32 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c · 39 unmodified lines
1277 goto free;1280 goto free;
1278 }1281 }
1279 1282
1280 if (cblk->npasses > 1)1283 if (z_blk > 1)
1281 jpeg2000_decode_sigprop_segment(cblk, width, height, quad_buf_width, Dref, Lref,1284 jpeg2000_decode_sigprop_segment(cblk, width, height, quad_buf_width, Dref, Lref,
1282 pLSB - 1, sample_buf, block_states);1285 pLSB - 1, sample_buf, block_states);
1283 1286
1284 if (cblk->npasses > 2) {1287 if (z_blk > 2)
1285 1288 jpeg2000_decode_magref_segment(width, height, quad_buf_width, Dref, Lref,
1286 if (Lref < 2){1289 pLSB - 1, sample_buf, block_states);
1287 av_log(s->avctx,AV_LOG_ERROR,"Invalid magnitude refinement length\n");
1288 ret = AVERROR_INVALIDDATA;
1289 goto free;
1290 }
1291 if ((ret = jpeg2000_decode_magref_segment(width, height, quad_buf_width, Dref, Lref,
1292 pLSB - 1, sample_buf, block_states)) < 0)
1293 goto free;
1294 }
1295 1290
1296 pLSB = 31 - M_b;1291 pLSB = 31 - M_b;
1297 1292
1298 /* Reconstruct the sample values */1293 /* Reconstruct the sample values */
1299 for (int y = 0; y < height; y++) {1294 for (int y = 0; y < height; y++) {
1300 for (int x = 0; x < width; x++) {1295 for (int x = 0; x < width; x++) {
1296 int32_t sign;
1297
1301 n = x + (y * t1->stride);1298 n = x + (y * t1->stride);
1302 val = sample_buf[x + (y * quad_buf_width)];1299 val = sample_buf[x + (y * quad_buf_width)];
1300 sign = val & INT32_MIN;
1301 val &= INT32_MAX;
1302 /* ROI shift, if necessary */
1303 if (roi_shift && (((uint32_t)val & ~mask) == 0))
1304 val <<= roi_shift;
1303 /* Convert sign-magnitude to two's complement. */1305 /* Convert sign-magnitude to two's complement. */
1304 val = val >> 31 ? 0x80000000 - val : val;1306 if (sign)
1307 val = -val;
1308 /* Shift down to 1 bit upper from decimal point for reconstruction value (= 0.5) */
1305 val >>= (pLSB - 1);1309 val >>= (pLSB - 1);
1306 t1->data[n] = val;1310 t1->data[n] = val;
1307 }1311 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t