linux/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2016 MediaTek Inc.
   3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
   4 *         Rick Chang <rick.chang@mediatek.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/videodev2.h>
  18
  19#include "mtk_jpeg_parse.h"
  20
  21#define TEM     0x01
  22#define SOF0    0xc0
  23#define RST     0xd0
  24#define SOI     0xd8
  25#define EOI     0xd9
  26
  27struct mtk_jpeg_stream {
  28        u8 *addr;
  29        u32 size;
  30        u32 curr;
  31};
  32
  33static int read_byte(struct mtk_jpeg_stream *stream)
  34{
  35        if (stream->curr >= stream->size)
  36                return -1;
  37        return stream->addr[stream->curr++];
  38}
  39
  40static int read_word_be(struct mtk_jpeg_stream *stream, u32 *word)
  41{
  42        u32 temp;
  43        int byte;
  44
  45        byte = read_byte(stream);
  46        if (byte == -1)
  47                return -1;
  48        temp = byte << 8;
  49        byte = read_byte(stream);
  50        if (byte == -1)
  51                return -1;
  52        *word = (u32)byte | temp;
  53
  54        return 0;
  55}
  56
  57static void read_skip(struct mtk_jpeg_stream *stream, long len)
  58{
  59        if (len <= 0)
  60                return;
  61        while (len--)
  62                read_byte(stream);
  63}
  64
  65static bool mtk_jpeg_do_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
  66                              u32 src_size)
  67{
  68        bool notfound = true;
  69        struct mtk_jpeg_stream stream;
  70
  71        stream.addr = src_addr_va;
  72        stream.size = src_size;
  73        stream.curr = 0;
  74
  75        while (notfound) {
  76                int i, length, byte;
  77                u32 word;
  78
  79                byte = read_byte(&stream);
  80                if (byte == -1)
  81                        return false;
  82                if (byte != 0xff)
  83                        continue;
  84                do
  85                        byte = read_byte(&stream);
  86                while (byte == 0xff);
  87                if (byte == -1)
  88                        return false;
  89                if (byte == 0)
  90                        continue;
  91
  92                length = 0;
  93                switch (byte) {
  94                case SOF0:
  95                        /* length */
  96                        if (read_word_be(&stream, &word))
  97                                break;
  98
  99                        /* precision */
 100                        if (read_byte(&stream) == -1)
 101                                break;
 102
 103                        if (read_word_be(&stream, &word))
 104                                break;
 105                        param->pic_h = word;
 106
 107                        if (read_word_be(&stream, &word))
 108                                break;
 109                        param->pic_w = word;
 110
 111                        param->comp_num = read_byte(&stream);
 112                        if (param->comp_num != 1 && param->comp_num != 3)
 113                                break;
 114
 115                        for (i = 0; i < param->comp_num; i++) {
 116                                param->comp_id[i] = read_byte(&stream);
 117                                if (param->comp_id[i] == -1)
 118                                        break;
 119
 120                                /* sampling */
 121                                byte = read_byte(&stream);
 122                                if (byte == -1)
 123                                        break;
 124                                param->sampling_w[i] = (byte >> 4) & 0x0F;
 125                                param->sampling_h[i] = byte & 0x0F;
 126
 127                                param->qtbl_num[i] = read_byte(&stream);
 128                                if (param->qtbl_num[i] == -1)
 129                                        break;
 130                        }
 131
 132                        notfound = !(i == param->comp_num);
 133                        break;
 134                case RST ... RST + 7:
 135                case SOI:
 136                case EOI:
 137                case TEM:
 138                        break;
 139                default:
 140                        if (read_word_be(&stream, &word))
 141                                break;
 142                        length = (long)word - 2;
 143                        read_skip(&stream, length);
 144                        break;
 145                }
 146        }
 147
 148        return !notfound;
 149}
 150
 151bool mtk_jpeg_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
 152                    u32 src_size)
 153{
 154        if (!mtk_jpeg_do_parse(param, src_addr_va, src_size))
 155                return false;
 156        if (mtk_jpeg_dec_fill_param(param))
 157                return false;
 158
 159        return true;
 160}
 161