brintos

brintos / linux-shallow public Read only

0
0
Text · 2.8 KiB · bb9cdc9 Raw
148 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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		do72			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}148