File Index
Files and directories
Sign in
FILE

mtk_jpeg_dec_parse.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_parse.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2016 MediaTek Inc.
  4 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
  5 *         Rick Chang <rick.chang@mediatek.com>
  6 */
  7
  8#include <linux/kernel.h>
  9#include <linux/videodev2.h>
 10#include <media/jpeg.h>
 11
 12#include "mtk_jpeg_dec_parse.h"
 13
 14struct mtk_jpeg_stream {
 15	u8 *addr;
 16	u32 size;
 17	u32 curr;
 18};
 19
 20static int read_byte(struct mtk_jpeg_stream *stream)
 21{
 22	if (stream->curr >= stream->size)
 23		return -1;
 24	return stream->addr[stream->curr++];
 25}
 26
 27static int read_word_be(struct mtk_jpeg_stream *stream, u32 *word)
 28{
 29	u32 temp;
 30	int byte;
 31
 32	byte = read_byte(stream);
 33	if (byte == -1)
 34		return -1;
 35	temp = byte << 8;
 36	byte = read_byte(stream);
 37	if (byte == -1)
 38		return -1;
 39	*word = (u32)byte | temp;
 40
 41	return 0;
 42}
 43
 44static void read_skip(struct mtk_jpeg_stream *stream, long len)
 45{
 46	if (len <= 0)
 47		return;
 48	while (len--)
 49		read_byte(stream);
 50}
 51
 52static bool mtk_jpeg_do_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
 53			      u32 src_size)
 54{
 55	bool notfound = true;
 56	struct mtk_jpeg_stream stream;
 57
 58	stream.addr = src_addr_va;
 59	stream.size = src_size;
 60	stream.curr = 0;
 61
 62	while (notfound) {
 63		int i, length, byte;
 64		u32 word;
 65
 66		byte = read_byte(&stream);
 67		if (byte == -1)
 68			return false;
 69		if (byte != 0xff)
 70			continue;
 71		do
 72			byte = read_byte(&stream);
 73		while (byte == 0xff);
 74		if (byte == -1)
 75			return false;
 76		if (byte == 0)
 77			continue;
 78
 79		length = 0;
 80		switch (byte) {
 81		case JPEG_MARKER_SOF0:
 82			/* length */
 83			if (read_word_be(&stream, &word))
 84				break;
 85
 86			/* precision */
 87			if (read_byte(&stream) == -1)
 88				break;
 89
 90			if (read_word_be(&stream, &word))
 91				break;
 92			param->pic_h = word;
 93
 94			if (read_word_be(&stream, &word))
 95				break;
 96			param->pic_w = word;
 97
 98			param->comp_num = read_byte(&stream);
 99			if (param->comp_num != 1 && param->comp_num != 3)
100				break;
101
102			for (i = 0; i < param->comp_num; i++) {
103				param->comp_id[i] = read_byte(&stream);
104				if (param->comp_id[i] == -1)
105					break;
106
107				/* sampling */
108				byte = read_byte(&stream);
109				if (byte == -1)
110					break;
111				param->sampling_w[i] = (byte >> 4) & 0x0F;
112				param->sampling_h[i] = byte & 0x0F;
113
114				param->qtbl_num[i] = read_byte(&stream);
115				if (param->qtbl_num[i] == -1)
116					break;
117			}
118
119			notfound = !(i == param->comp_num);
120			break;
121		case JPEG_MARKER_RST ... JPEG_MARKER_RST + 7:
122		case JPEG_MARKER_SOI:
123		case JPEG_MARKER_EOI:
124		case JPEG_MARKER_TEM:
125			break;
126		default:
127			if (read_word_be(&stream, &word))
128				break;
129			length = (long)word - 2;
130			read_skip(&stream, length);
131			break;
132		}
133	}
134
135	return !notfound;
136}
137
138bool mtk_jpeg_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
139		    u32 src_size)
140{
141	if (!mtk_jpeg_do_parse(param, src_addr_va, src_size))
142		return false;
143	if (mtk_jpeg_dec_fill_param(param))
144		return false;
145
146	return true;
147}
~/ Read-only file preview.