media: coda: jpeg: support optimized huffman tables
authorAdrian Ratiu <adrian.ratiu@collabora.com>
Tue, 24 Mar 2020 16:04:29 +0000 (17:04 +0100)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 14 Apr 2020 09:57:02 +0000 (11:57 +0200)
Each jpeg can have the huffman tables optimized for its specific content
meaning that the table lenghts and values don't match the standard table
of substitutions so there's no reason to hardcode and expect the standard
lengths, otherwise we just end up rejecting optimized jpegs altogether.

Tested on CODA960.

Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/platform/coda/coda-jpeg.c

index 4512b2569b6be8cae90f22b86740a5000855f09f..00d19859db500075f85dd716b9a5e6d8129ea1ce 100644 (file)
@@ -339,7 +339,10 @@ int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb)
                        v4l2_err(&dev->v4l2_dev, "missing Huffman table\n");
                        return -EINVAL;
                }
-               if (huffman_tables[i].length != ((i & 2) ? 178 : 28)) {
+               /* AC tables should be between 17 -> 178, DC between 17 -> 28 */
+               if (huffman_tables[i].length < 17 ||
+                   huffman_tables[i].length > 178 ||
+                   ((i & 2) == 0 && huffman_tables[i].length > 28)) {
                        v4l2_err(&dev->v4l2_dev,
                                 "invalid Huffman table %d length: %zu\n",
                                 i, huffman_tables[i].length);
@@ -353,10 +356,12 @@ int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb)
                        return -ENOMEM;
                ctx->params.jpeg_huff_tab = huff_tab;
        }
-       memcpy(huff_tab->luma_dc, huffman_tables[0].start, 16 + 12);
-       memcpy(huff_tab->chroma_dc, huffman_tables[1].start, 16 + 12);
-       memcpy(huff_tab->luma_ac, huffman_tables[2].start, 16 + 162);
-       memcpy(huff_tab->chroma_ac, huffman_tables[3].start, 16 + 162);
+
+       memset(huff_tab, 0, sizeof(*huff_tab));
+       memcpy(huff_tab->luma_dc, huffman_tables[0].start, huffman_tables[0].length);
+       memcpy(huff_tab->chroma_dc, huffman_tables[1].start, huffman_tables[1].length);
+       memcpy(huff_tab->luma_ac, huffman_tables[2].start, huffman_tables[2].length);
+       memcpy(huff_tab->chroma_ac, huffman_tables[3].start, huffman_tables[3].length);
 
        /* check scan header */
        for (i = 0; i < scan_header.num_components; i++) {