You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	j2k/jpeg2000: log2_prec size cleanup
This also changes the cblk size storage method to what jpeg2000 uses Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		| @@ -174,6 +174,7 @@ void ff_j2k_set_significant(Jpeg2000T1Context *t1, int x, int y, | ||||
|  | ||||
| int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, Jpeg2000QuantStyle *qntsty, int cbps, int dx, int dy) | ||||
| { | ||||
|     uint8_t log2_band_prec_width, log2_band_prec_height; | ||||
|     int reslevelno, bandno, gbandno = 0, ret, i, j, csize = 1; | ||||
|  | ||||
|     if (ret=ff_j2k_dwt_init(&comp->dwt, comp->coord, codsty->nreslevels-1, codsty->transform)) | ||||
| @@ -195,6 +196,9 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, | ||||
|             for (j = 0; j < 2; j++) | ||||
|                 reslevel->coord[i][j] = | ||||
|                     ff_jpeg2000_ceildivpow2(comp->coord[i][j], declvl - 1); | ||||
|         // update precincts size: 2^n value | ||||
|         reslevel->log2_prec_width  = codsty->log2_prec_widths[reslevelno]; | ||||
|         reslevel->log2_prec_height = codsty->log2_prec_heights[reslevelno]; | ||||
|  | ||||
|         if (reslevelno == 0) | ||||
|             reslevel->nbands = 1; | ||||
| @@ -204,14 +208,14 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, | ||||
|         if (reslevel->coord[0][1] == reslevel->coord[0][0]) | ||||
|             reslevel->num_precincts_x = 0; | ||||
|         else | ||||
|             reslevel->num_precincts_x = ff_jpeg2000_ceildivpow2(reslevel->coord[0][1], codsty->log2_prec_width) | ||||
|                                         - (reslevel->coord[0][0] >> codsty->log2_prec_width); | ||||
|             reslevel->num_precincts_x = ff_jpeg2000_ceildivpow2(reslevel->coord[0][1], reslevel->log2_prec_width) | ||||
|                                         - (reslevel->coord[0][0] >> reslevel->log2_prec_width); | ||||
|  | ||||
|         if (reslevel->coord[1][1] == reslevel->coord[1][0]) | ||||
|             reslevel->num_precincts_y = 0; | ||||
|         else | ||||
|             reslevel->num_precincts_y = ff_jpeg2000_ceildivpow2(reslevel->coord[1][1], codsty->log2_prec_height) | ||||
|                                         - (reslevel->coord[1][0] >> codsty->log2_prec_height); | ||||
|             reslevel->num_precincts_y = ff_jpeg2000_ceildivpow2(reslevel->coord[1][1], reslevel->log2_prec_height) | ||||
|                                         - (reslevel->coord[1][0] >> reslevel->log2_prec_height); | ||||
|  | ||||
|         reslevel->band = av_malloc_array(reslevel->nbands, sizeof(*reslevel->band)); | ||||
|         if (!reslevel->band) | ||||
| @@ -233,22 +237,45 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, | ||||
|             } else | ||||
|                 band->stepsize = 1 << 13; | ||||
|  | ||||
|             if (reslevelno == 0) {  // the same everywhere | ||||
|                 band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width-1); | ||||
|                 band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height-1); | ||||
|             if (reslevelno == 0) { | ||||
|                 /* for reslevelno = 0, only one band, x0_b = y0_b = 0 */ | ||||
|                 for (i = 0; i < 2; i++) | ||||
|                     for (j = 0; j < 2; j++) | ||||
|                         band->coord[i][j] = ff_jpeg2000_ceildivpow2(comp->coord[i][j], declvl-1); | ||||
|             } else{ | ||||
|                 band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width); | ||||
|                 band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height); | ||||
|                         band->coord[i][j] = | ||||
|                             ff_jpeg2000_ceildivpow2(comp->coord[i][j], | ||||
|                                                     declvl - 1); | ||||
|  | ||||
|                 log2_band_prec_width  = reslevel->log2_prec_width; | ||||
|                 log2_band_prec_height = reslevel->log2_prec_height; | ||||
|                 /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */ | ||||
|                 band->log2_cblk_width  = FFMIN(codsty->log2_cblk_width, | ||||
|                                                reslevel->log2_prec_width); | ||||
|                 band->log2_cblk_height = FFMIN(codsty->log2_cblk_height, | ||||
|                                                reslevel->log2_prec_height); | ||||
|             } else{ | ||||
|                 /* 3 bands x0_b = 1 y0_b = 0; x0_b = 0 y0_b = 1; x0_b = y0_b = 1 */ | ||||
|                 /* x0_b and y0_b are computed with ((bandno + 1 >> i) & 1) */ | ||||
|                 for (i = 0; i < 2; i++) | ||||
|                     for (j = 0; j < 2; j++) | ||||
|                         band->coord[i][j] = ff_jpeg2000_ceildivpow2(comp->coord[i][j] - (((bandno+1>>i)&1) << declvl-1), declvl); | ||||
|                         /* Formula example for tbx_0 = ceildiv((tcx_0 - 2 ^ (declvl - 1) * x0_b) / declvl) */ | ||||
|                         band->coord[i][j] = | ||||
|                             ff_jpeg2000_ceildivpow2(comp->coord[i][j] - | ||||
|                                                     (((bandno + 1 >> i) & 1) << declvl - 1), | ||||
|                                                     declvl); | ||||
|                 /* TODO: Manage case of 3 band offsets here or | ||||
|                  * in coding/decoding function? */ | ||||
|  | ||||
|                 /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */ | ||||
|                 band->log2_cblk_width  = FFMIN(codsty->log2_cblk_width, | ||||
|                                                reslevel->log2_prec_width - 1); | ||||
|                 band->log2_cblk_height = FFMIN(codsty->log2_cblk_height, | ||||
|                                                reslevel->log2_prec_height - 1); | ||||
|  | ||||
|                 log2_band_prec_width  = reslevel->log2_prec_width  - 1; | ||||
|                 log2_band_prec_height = reslevel->log2_prec_height - 1; | ||||
|             } | ||||
|             band->cblknx = ff_jpeg2000_ceildiv(band->coord[0][1], band->codeblock_width)  - band->coord[0][0] / band->codeblock_width; | ||||
|             band->cblkny = ff_jpeg2000_ceildiv(band->coord[1][1], band->codeblock_height) - band->coord[1][0] / band->codeblock_height; | ||||
|             band->cblknx = ff_jpeg2000_ceildivpow2(band->coord[0][1], band->log2_cblk_width)  - (band->coord[0][0] >> band->log2_cblk_width); | ||||
|             band->cblkny = ff_jpeg2000_ceildivpow2(band->coord[1][1], band->log2_cblk_height) - (band->coord[1][0] >> band->log2_cblk_height); | ||||
|  | ||||
|             for (j = 0; j < 2; j++) | ||||
|                 band->coord[0][j] = ff_jpeg2000_ceildiv(band->coord[0][j], dx); | ||||
| @@ -279,11 +306,11 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, | ||||
|             } | ||||
|  | ||||
|             y0 = band->coord[1][0]; | ||||
|             y1 = ((band->coord[1][0] + (1<<codsty->log2_prec_height)) & ~((1<<codsty->log2_prec_height)-1)) - y0; | ||||
|             y1 = ((band->coord[1][0] + (1<<reslevel->log2_prec_height)) & ~((1<<reslevel->log2_prec_height)-1)) - y0; | ||||
|             yi0 = 0; | ||||
|             yi1 = ff_jpeg2000_ceildivpow2(y1 - y0, codsty->log2_cblk_height) << codsty->log2_cblk_height; | ||||
|             yi1 = FFMIN(yi1, band->cblkny); | ||||
|             cblkperprech = 1<<(codsty->log2_prec_height - codsty->log2_cblk_height); | ||||
|             cblkperprech = 1<<(reslevel->log2_prec_height - codsty->log2_cblk_height); | ||||
|             for (precy = 0, precno = 0; precy < reslevel->num_precincts_y; precy++) { | ||||
|                 for (precx = 0; precx < reslevel->num_precincts_x; precx++, precno++) { | ||||
|                     band->prec[precno].yi0 = yi0; | ||||
| @@ -294,12 +321,12 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, | ||||
|                 yi1 = FFMIN(yi1, band->cblkny); | ||||
|             } | ||||
|             x0 = band->coord[0][0]; | ||||
|             x1 = ((band->coord[0][0] + (1<<codsty->log2_prec_width)) & ~((1<<codsty->log2_prec_width)-1)) - x0; | ||||
|             x1 = ((band->coord[0][0] + (1<<reslevel->log2_prec_width)) & ~((1<<reslevel->log2_prec_width)-1)) - x0; | ||||
|             xi0 = 0; | ||||
|             xi1 = ff_jpeg2000_ceildivpow2(x1 - x0, codsty->log2_cblk_width) << codsty->log2_cblk_width; | ||||
|             xi1 = FFMIN(xi1, band->cblknx); | ||||
|  | ||||
|             cblkperprecw = 1<<(codsty->log2_prec_width - codsty->log2_cblk_width); | ||||
|             cblkperprecw = 1<<(reslevel->log2_prec_width - codsty->log2_cblk_width); | ||||
|             for (precx = 0, precno = 0; precx < reslevel->num_precincts_x; precx++) { | ||||
|                 for (precy = 0; precy < reslevel->num_precincts_y; precy++, precno = 0) { | ||||
|                     Jpeg2000Prec *prec = band->prec + precno; | ||||
|   | ||||
| @@ -130,8 +130,6 @@ typedef struct Jpeg2000CodingStyle { | ||||
|             log2_cblk_height; // exponent of codeblock size | ||||
|     uint8_t transform;        // DWT type | ||||
|     uint8_t csty;             // coding style | ||||
|     uint8_t log2_prec_width, | ||||
|             log2_prec_height; // precinct size | ||||
|     uint8_t nlayers;          // number of layers | ||||
|     uint8_t mct;              // multiple component transformation | ||||
|     uint8_t cblk_style;       // codeblock coding style | ||||
| @@ -172,7 +170,7 @@ typedef struct Jpeg2000Prec { | ||||
|  | ||||
| typedef struct Jpeg2000Band { | ||||
|     uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} | ||||
|     uint16_t codeblock_width, codeblock_height; | ||||
|     uint16_t log2_cblk_width, log2_cblk_height; | ||||
|     uint16_t cblknx, cblkny; | ||||
|     uint32_t stepsize; // quantization stepsize (* 2^13) | ||||
|     Jpeg2000Prec *prec; | ||||
|   | ||||
| @@ -230,9 +230,15 @@ static int get_siz(Jpeg2000DecoderContext *s) | ||||
| /** get common part for COD and COC segments */ | ||||
| static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) | ||||
| { | ||||
|     uint8_t byte; | ||||
|  | ||||
|     if (bytestream2_get_bytes_left(&s->g) < 5) | ||||
|         return AVERROR(EINVAL); | ||||
|           c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1 | ||||
|     c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1 | ||||
|     if (c->nreslevels >= JPEG2000_MAX_RESLEVELS) { | ||||
|         av_log(s->avctx, AV_LOG_ERROR, "nreslevels %d is invalid\n", c->nreslevels); | ||||
|         return AVERROR_INVALIDDATA; | ||||
|     } | ||||
|  | ||||
|     c->log2_cblk_width  = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width | ||||
|     c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height | ||||
| @@ -250,9 +256,14 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) | ||||
|     c->transform = bytestream2_get_byteu(&s->g); // transformation | ||||
|     if (c->csty & JPEG2000_CSTY_PREC) { | ||||
|         int i; | ||||
|  | ||||
|         for (i = 0; i < c->nreslevels; i++) | ||||
|             bytestream2_get_byte(&s->g); | ||||
|         for (i = 0; i < c->nreslevels; i++) { | ||||
|             byte = bytestream2_get_byte(&s->g); | ||||
|             c->log2_prec_widths[i]  =  byte       & 0x0F;    // precinct PPx | ||||
|             c->log2_prec_heights[i] = (byte >> 4) & 0x0F;    // precinct PPy | ||||
|         } | ||||
|     } else { | ||||
|         memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths )); | ||||
|         memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights)); | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| @@ -266,9 +277,6 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, uint8_t *p | ||||
|     if (bytestream2_get_bytes_left(&s->g) < 5) | ||||
|         return AVERROR(EINVAL); | ||||
|  | ||||
|     tmp.log2_prec_width  = | ||||
|     tmp.log2_prec_height = 15; | ||||
|  | ||||
|     tmp.csty = bytestream2_get_byteu(&s->g); | ||||
|  | ||||
|     // get progression order | ||||
| @@ -756,7 +764,7 @@ static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) | ||||
|  | ||||
|                 yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0]; | ||||
|                 y0 = yy0; | ||||
|                 yy1 = FFMIN(ff_jpeg2000_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height, | ||||
|                 yy1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[1][0] + 1,  band->log2_cblk_height) << band->log2_cblk_height, | ||||
|                             band->coord[1][1]) - band->coord[1][0] + yy0; | ||||
|  | ||||
|                 if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) | ||||
| @@ -768,7 +776,7 @@ static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) | ||||
|                     else | ||||
|                         xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0]; | ||||
|                     x0 = xx0; | ||||
|                     xx1 = FFMIN(ff_jpeg2000_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width, | ||||
|                     xx1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[0][0] + 1, band->log2_cblk_width) << band->log2_cblk_width, | ||||
|                                 band->coord[0][1]) - band->coord[0][0] + xx0; | ||||
|  | ||||
|                     for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++) { | ||||
| @@ -792,10 +800,10 @@ static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) | ||||
|                             } | ||||
|                         } | ||||
|                         xx0 = xx1; | ||||
|                         xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0); | ||||
|                         xx1 = FFMIN(xx1 + (1 << band->log2_cblk_width), band->coord[0][1] - band->coord[0][0] + x0); | ||||
|                     } | ||||
|                     yy0 = yy1; | ||||
|                     yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0); | ||||
|                     yy1 = FFMIN(yy1 + (1 << band->log2_cblk_height), band->coord[1][1] - band->coord[1][0] + y0); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -821,7 +821,7 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno | ||||
|                 int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos; | ||||
|                 yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0]; | ||||
|                 y0 = yy0; | ||||
|                 yy1 = FFMIN(ff_jpeg2000_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height, | ||||
|                 yy1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[1][0] + 1, band->log2_cblk_height) << band->log2_cblk_height, | ||||
|                             band->coord[1][1]) - band->coord[1][0] + yy0; | ||||
|  | ||||
|                 if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) | ||||
| @@ -835,7 +835,7 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno | ||||
|                     else | ||||
|                         xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0]; | ||||
|                     x0 = xx0; | ||||
|                     xx1 = FFMIN(ff_jpeg2000_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width, | ||||
|                     xx1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[0][0] + 1, band->log2_cblk_width) << band->log2_cblk_width, | ||||
|                                 band->coord[0][1]) - band->coord[0][0] + xx0; | ||||
|  | ||||
|                     for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){ | ||||
| @@ -860,10 +860,10 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno | ||||
|                         encode_cblk(s, &t1, band->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0, | ||||
|                                     bandpos, codsty->nreslevels - reslevelno - 1); | ||||
|                         xx0 = xx1; | ||||
|                         xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0); | ||||
|                         xx1 = FFMIN(xx1 + (1 << band->log2_cblk_width), band->coord[0][1] - band->coord[0][0] + x0); | ||||
|                     } | ||||
|                     yy0 = yy1; | ||||
|                     yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0); | ||||
|                     yy1 = FFMIN(yy1 + (1 << band->log2_cblk_height), band->coord[1][1] - band->coord[1][0] + y0); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -969,8 +969,8 @@ static av_cold int j2kenc_init(AVCodecContext *avctx) | ||||
|  | ||||
|     // defaults: | ||||
|     // TODO: implement setting non-standard precinct size | ||||
|     codsty->log2_prec_width  = 15; | ||||
|     codsty->log2_prec_height = 15; | ||||
|     memset(codsty->log2_prec_widths , 15, sizeof(codsty->log2_prec_widths )); | ||||
|     memset(codsty->log2_prec_heights, 15, sizeof(codsty->log2_prec_heights)); | ||||
|     codsty->nreslevels       = 7; | ||||
|     codsty->log2_cblk_width  = 4; | ||||
|     codsty->log2_cblk_height = 4; | ||||
|   | ||||
| @@ -134,8 +134,6 @@ typedef struct Jpeg2000CodingStyle { | ||||
|             log2_cblk_height; // exponent of codeblock size | ||||
|     uint8_t transform;        // DWT type | ||||
|     uint8_t csty;             // coding style | ||||
|     uint8_t log2_prec_width, | ||||
|             log2_prec_height; // precinct size | ||||
|     uint8_t nlayers;          // number of layers | ||||
|     uint8_t mct;              // multiple component transformation | ||||
|     uint8_t cblk_style;       // codeblock coding style | ||||
|   | ||||
| @@ -256,6 +256,10 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) | ||||
|     if (bytestream2_get_bytes_left(&s->g) < 5) | ||||
|         return AVERROR(EINVAL); | ||||
|     c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1 | ||||
|     if (c->nreslevels >= JPEG2000_MAX_RESLEVELS) { | ||||
|         av_log(s->avctx, AV_LOG_ERROR, "nreslevels %d is invalid\n", c->nreslevels); | ||||
|         return AVERROR_INVALIDDATA; | ||||
|     } | ||||
|  | ||||
|     /* compute number of resolution levels to decode */ | ||||
|     if (c->nreslevels < s->reduction_factor) | ||||
| @@ -289,6 +293,9 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) | ||||
|             c->log2_prec_widths[i]  =  byte       & 0x0F;    // precinct PPx | ||||
|             c->log2_prec_heights[i] = (byte >> 4) & 0x0F;    // precinct PPy | ||||
|         } | ||||
|     } else { | ||||
|         memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths )); | ||||
|         memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights)); | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| @@ -303,9 +310,6 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, | ||||
|     if (bytestream2_get_bytes_left(&s->g) < 5) | ||||
|         return AVERROR(EINVAL); | ||||
|  | ||||
|     tmp.log2_prec_width  = | ||||
|     tmp.log2_prec_height = 15; | ||||
|  | ||||
|     tmp.csty = bytestream2_get_byteu(&s->g); | ||||
|  | ||||
|     // get progression order | ||||
|   | ||||
		Reference in New Issue
	
	Block a user