mtk_jpeg_parse.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. #include <linux/kernel.h>
  16. #include <linux/videodev2.h>
  17. #include "mtk_jpeg_parse.h"
  18. #define TEM 0x01
  19. #define SOF0 0xc0
  20. #define RST 0xd0
  21. #define SOI 0xd8
  22. #define EOI 0xd9
  23. struct mtk_jpeg_stream {
  24. u8 *addr;
  25. u32 size;
  26. u32 curr;
  27. };
  28. static int read_byte(struct mtk_jpeg_stream *stream)
  29. {
  30. if (stream->curr >= stream->size)
  31. return -1;
  32. return stream->addr[stream->curr++];
  33. }
  34. static int read_word_be(struct mtk_jpeg_stream *stream, u32 *word)
  35. {
  36. u32 temp;
  37. int byte;
  38. byte = read_byte(stream);
  39. if (byte == -1)
  40. return -1;
  41. temp = byte << 8;
  42. byte = read_byte(stream);
  43. if (byte == -1)
  44. return -1;
  45. *word = (u32)byte | temp;
  46. return 0;
  47. }
  48. static void read_skip(struct mtk_jpeg_stream *stream, long len)
  49. {
  50. if (len <= 0)
  51. return;
  52. while (len--)
  53. read_byte(stream);
  54. }
  55. static bool mtk_jpeg_do_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
  56. u32 src_size)
  57. {
  58. bool notfound = true;
  59. struct mtk_jpeg_stream stream;
  60. stream.addr = src_addr_va;
  61. stream.size = src_size;
  62. stream.curr = 0;
  63. while (notfound) {
  64. int i, length, byte;
  65. u32 word;
  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. length = 0;
  79. switch (byte) {
  80. case SOF0:
  81. /* length */
  82. if (read_word_be(&stream, &word))
  83. break;
  84. /* precision */
  85. if (read_byte(&stream) == -1)
  86. break;
  87. if (read_word_be(&stream, &word))
  88. break;
  89. param->pic_h = word;
  90. if (read_word_be(&stream, &word))
  91. break;
  92. param->pic_w = word;
  93. param->comp_num = read_byte(&stream);
  94. if (param->comp_num != 1 && param->comp_num != 3)
  95. break;
  96. for (i = 0; i < param->comp_num; i++) {
  97. param->comp_id[i] = read_byte(&stream);
  98. if (param->comp_id[i] == -1)
  99. break;
  100. /* sampling */
  101. byte = read_byte(&stream);
  102. if (byte == -1)
  103. break;
  104. param->sampling_w[i] = (byte >> 4) & 0x0F;
  105. param->sampling_h[i] = byte & 0x0F;
  106. param->qtbl_num[i] = read_byte(&stream);
  107. if (param->qtbl_num[i] == -1)
  108. break;
  109. }
  110. notfound = !(i == param->comp_num);
  111. break;
  112. case RST ... RST + 7:
  113. case SOI:
  114. case EOI:
  115. case TEM:
  116. break;
  117. default:
  118. if (read_word_be(&stream, &word))
  119. break;
  120. length = (long)word - 2;
  121. read_skip(&stream, length);
  122. break;
  123. }
  124. }
  125. return !notfound;
  126. }
  127. bool mtk_jpeg_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
  128. u32 src_size)
  129. {
  130. if (!mtk_jpeg_do_parse(param, src_addr_va, src_size))
  131. return false;
  132. if (mtk_jpeg_dec_fill_param(param))
  133. return false;
  134. return true;
  135. }