[FFmpeg-devel] [RFC PATCH v5 2/3] libavcodec/j2kenc: Fix tag tree coding
gautamramk at gmail.com
gautamramk at gmail.com
Tue Aug 25 16:55:44 EEST 2020
From: Gautam Ramakrishnan <gautamramk at gmail.com>
The implementation of tag tree encoding was incorrect.
However, this error was not visible as the current j2k
encoder encodes only 1 layer.
This patch fixes tag tree coding for JPEG2000 such tag
tree coding would work for multi layer encoding.
---
libavcodec/j2kenc.c | 41 +++++++++++++++++++++++++----------------
libavcodec/jpeg2000.c | 9 +++++----
libavcodec/jpeg2000.h | 3 ++-
3 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c
index 16863f8e8c..87acd2d5c9 100644
--- a/libavcodec/j2kenc.c
+++ b/libavcodec/j2kenc.c
@@ -242,27 +242,36 @@ static void j2k_flush(Jpeg2000EncoderContext *s)
static void tag_tree_code(Jpeg2000EncoderContext *s, Jpeg2000TgtNode *node, int threshold)
{
Jpeg2000TgtNode *stack[30];
- int sp = 1, curval = 0;
- stack[0] = node;
+ int sp = -1, curval = 0;
- node = node->parent;
- while(node){
- if (node->vis){
- curval = node->val;
- break;
- }
- node->vis++;
- stack[sp++] = node;
+ while(node->parent){
+ stack[++sp] = node;
node = node->parent;
}
- while(--sp >= 0){
- if (stack[sp]->val >= threshold){
+
+ while (1) {
+ if (curval > node->temp_val)
+ node->temp_val = curval;
+ else {
+ curval = node->temp_val;
+ }
+
+ if (node->val >= threshold) {
put_bits(s, 0, threshold - curval);
- break;
+ curval = threshold;
+ } else {
+ put_bits(s, 0, node->val - curval);
+ curval = node->val;
+ if (!node->vis) {
+ put_bits(s, 1, 1);
+ node->vis = 1;
+ }
}
- put_bits(s, 0, stack[sp]->val - curval);
- put_bits(s, 1, 1);
- curval = stack[sp]->val;
+
+ node->temp_val = curval;
+ if (sp < 0)
+ break;
+ node = stack[sp--];
}
}
diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c
index 26e09fbe38..2e26bc5b00 100644
--- a/libavcodec/jpeg2000.c
+++ b/libavcodec/jpeg2000.c
@@ -82,12 +82,13 @@ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h)
return res;
}
-void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h)
+void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h, int val)
{
int i, siz = ff_tag_tree_size(w, h);
for (i = 0; i < siz; i++) {
- t[i].val = 0;
+ t[i].val = val;
+ t[i].temp_val = 0;
t[i].vis = 0;
}
}
@@ -567,8 +568,8 @@ void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty)
Jpeg2000Band *band = rlevel->band + bandno;
for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++) {
Jpeg2000Prec *prec = band->prec + precno;
- ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height);
- ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height);
+ ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 0);
+ ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 0);
for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
Jpeg2000Cblk *cblk = prec->cblk + cblkno;
cblk->length = 0;
diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h
index c3437b02fe..a9f2e01632 100644
--- a/libavcodec/jpeg2000.h
+++ b/libavcodec/jpeg2000.h
@@ -127,6 +127,7 @@ typedef struct Jpeg2000T1Context {
typedef struct Jpeg2000TgtNode {
uint8_t val;
+ uint8_t temp_val;
uint8_t vis;
struct Jpeg2000TgtNode *parent;
} Jpeg2000TgtNode;
@@ -291,6 +292,6 @@ static inline int needs_termination(int style, int passno) {
}
int32_t ff_tag_tree_size(int w, int h);
-void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h);
+void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h, int val);
#endif /* AVCODEC_JPEG2000_H */
--
2.17.1
More information about the ffmpeg-devel
mailing list