Skip to content

Commit b8035f7

Browse files
mrabule1mchehab
authored andcommitted
media: Add parsing for APP14 data segment in jpeg helpers
According to Rec. ITU-T T.872 (06/2012) 6.5.3 APP14 segment is for color encoding, it contains a transform flag, which may have values of 0, 1 and 2 and are interpreted as follows: 0 - CMYK for images that are encoded with four components - RGB for images that are encoded with three components 1 - An image encoded with three components using YCbCr colour encoding. 2 - An image encoded with four components using YCCK colour encoding. This is used in imx-jpeg decoder, to distinguish between YUV444 and RGB24. Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.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>
1 parent b16ed1e commit b8035f7

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

drivers/media/v4l2-core/v4l2-jpeg.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ MODULE_LICENSE("GPL");
4545
#define DHP 0xffde /* hierarchical progression */
4646
#define EXP 0xffdf /* expand reference */
4747
#define APP0 0xffe0 /* application data */
48+
#define APP14 0xffee /* application data for colour encoding */
4849
#define APP15 0xffef
4950
#define JPG0 0xfff0 /* extensions */
5051
#define JPG13 0xfffd
@@ -444,6 +445,39 @@ static int jpeg_skip_segment(struct jpeg_stream *stream)
444445
return jpeg_skip(stream, len - 2);
445446
}
446447

448+
/* Rec. ITU-T T.872 (06/2012) 6.5.3 */
449+
static int jpeg_parse_app14_data(struct jpeg_stream *stream,
450+
enum v4l2_jpeg_app14_tf *tf)
451+
{
452+
int ret;
453+
int lp;
454+
int skip;
455+
456+
lp = jpeg_get_word_be(stream);
457+
if (lp < 0)
458+
return lp;
459+
460+
/* Check for "Adobe\0" in Ap1..6 */
461+
if (stream->curr + 6 > stream->end ||
462+
strncmp(stream->curr, "Adobe\0", 6))
463+
return -EINVAL;
464+
465+
/* get to Ap12 */
466+
ret = jpeg_skip(stream, 11);
467+
if (ret < 0)
468+
return ret;
469+
470+
ret = jpeg_get_byte(stream);
471+
if (ret < 0)
472+
return ret;
473+
474+
*tf = ret;
475+
476+
/* skip the rest of the segment, this ensures at least it is complete */
477+
skip = lp - 2 - 11;
478+
return jpeg_skip(stream, skip);
479+
}
480+
447481
/**
448482
* v4l2_jpeg_parse_header - locate marker segments and optionally parse headers
449483
* @buf: address of the JPEG buffer, should start with a SOI marker
@@ -476,6 +510,9 @@ int v4l2_jpeg_parse_header(void *buf, size_t len, struct v4l2_jpeg_header *out)
476510
if (marker != SOI)
477511
return -EINVAL;
478512

513+
/* init value to signal if this marker is not present */
514+
out->app14_tf = V4L2_JPEG_APP14_TF_UNKNOWN;
515+
479516
/* loop through marker segments */
480517
while ((marker = jpeg_next_marker(&stream)) >= 0) {
481518
switch (marker) {
@@ -519,7 +556,10 @@ int v4l2_jpeg_parse_header(void *buf, size_t len, struct v4l2_jpeg_header *out)
519556
ret = jpeg_parse_restart_interval(&stream,
520557
&out->restart_interval);
521558
break;
522-
559+
case APP14:
560+
ret = jpeg_parse_app14_data(&stream,
561+
&out->app14_tf);
562+
break;
523563
case SOS:
524564
ret = jpeg_reference_segment(&stream, &out->sos);
525565
if (ret < 0)

include/media/v4l2-jpeg.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,24 @@ struct v4l2_jpeg_scan_header {
8787
/* Ss, Se, Ah, and Al are not used by any driver */
8888
};
8989

90+
/**
91+
* enum v4l2_jpeg_app14_tf - APP14 transform flag
92+
* According to Rec. ITU-T T.872 (06/2012) 6.5.3
93+
* APP14 segment is for color encoding, it contains a transform flag,
94+
* which may have values of 0, 1 and 2 and are interpreted as follows:
95+
* @V4L2_JPEG_APP14_TF_CMYK_RGB: CMYK for images encoded with four components
96+
* RGB for images encoded with three components
97+
* @V4L2_JPEG_APP14_TF_YCBCR: an image encoded with three components using YCbCr
98+
* @V4L2_JPEG_APP14_TF_YCCK: an image encoded with four components using YCCK
99+
* @V4L2_JPEG_APP14_TF_UNKNOWN: indicate app14 is not present
100+
*/
101+
enum v4l2_jpeg_app14_tf {
102+
V4L2_JPEG_APP14_TF_CMYK_RGB = 0,
103+
V4L2_JPEG_APP14_TF_YCBCR = 1,
104+
V4L2_JPEG_APP14_TF_YCCK = 2,
105+
V4L2_JPEG_APP14_TF_UNKNOWN = -1,
106+
};
107+
90108
/**
91109
* struct v4l2_jpeg_header - parsed JPEG header
92110
* @sof: pointer to frame header and size
@@ -102,6 +120,7 @@ struct v4l2_jpeg_scan_header {
102120
* order, optional
103121
* @restart_interval: number of MCU per restart interval, Ri
104122
* @ecs_offset: buffer offset in bytes to the entropy coded segment
123+
* @app14_tf: transform flag from app14 data
105124
*
106125
* When this structure is passed to v4l2_jpeg_parse_header, the optional scan,
107126
* quantization_tables, and huffman_tables pointers must be initialized to NULL
@@ -121,6 +140,7 @@ struct v4l2_jpeg_header {
121140
struct v4l2_jpeg_reference *huffman_tables;
122141
u16 restart_interval;
123142
size_t ecs_offset;
143+
enum v4l2_jpeg_app14_tf app14_tf;
124144
};
125145

126146
int v4l2_jpeg_parse_header(void *buf, size_t len, struct v4l2_jpeg_header *out);

0 commit comments

Comments
 (0)