1/* 2 * Coda multi-standard codec IP - JPEG support functions 3 * 4 * Copyright (C) 2014 Philipp Zabel, Pengutronix 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 as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12#include <linux/kernel.h> 13#include <linux/swab.h> 14 15#include "coda.h" 16#include "trace.h" 17 18#define SOI_MARKER 0xffd8 19#define EOI_MARKER 0xffd9 20 21/* 22 * Typical Huffman tables for 8-bit precision luminance and 23 * chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3 24 */ 25 26static const unsigned char luma_dc_bits[16] = { 27 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 28 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29}; 30 31static const unsigned char luma_dc_value[12] = { 32 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 33 0x08, 0x09, 0x0a, 0x0b, 34}; 35 36static const unsigned char chroma_dc_bits[16] = { 37 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 38 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 39}; 40 41static const unsigned char chroma_dc_value[12] = { 42 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 43 0x08, 0x09, 0x0a, 0x0b, 44}; 45 46static const unsigned char luma_ac_bits[16] = { 47 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 48 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 49}; 50 51static const unsigned char luma_ac_value[162 + 2] = { 52 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 53 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 54 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 55 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 56 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 57 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 58 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 59 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 60 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 61 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 62 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 63 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 64 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 65 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 66 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 67 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 68 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 69 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 70 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 71 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 72 0xf9, 0xfa, /* padded to 32-bit */ 73}; 74 75static const unsigned char chroma_ac_bits[16] = { 76 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 77 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 78}; 79 80static const unsigned char chroma_ac_value[162 + 2] = { 81 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 82 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 83 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 84 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 85 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 86 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 87 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 88 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 89 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 90 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 91 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 92 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 93 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 94 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 95 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 96 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 97 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 98 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 99 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 100 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 101 0xf9, 0xfa, /* padded to 32-bit */ 102}; 103 104/* 105 * Quantization tables for luminance and chrominance components in 106 * zig-zag scan order from the Freescale i.MX VPU libaries 107 */ 108 109static unsigned char luma_q[64] = { 110 0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05, 111 0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0b, 112 0x08, 0x06, 0x06, 0x08, 0x0b, 0x0c, 0x0a, 0x0a, 113 0x0b, 0x0a, 0x0a, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 114 0x0c, 0x0c, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 0x0c, 115 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 116 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 117 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 118}; 119 120static unsigned char chroma_q[64] = { 121 0x07, 0x07, 0x07, 0x0d, 0x0c, 0x0d, 0x18, 0x10, 122 0x10, 0x18, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14, 123 0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c, 124 0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c, 125 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, 126 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 127 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 128 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 129}; 130 131struct coda_memcpy_desc { 132 int offset; 133 const void *src; 134 size_t len; 135}; 136 137static void coda_memcpy_parabuf(void *parabuf, 138 const struct coda_memcpy_desc *desc) 139{ 140 u32 *dst = parabuf + desc->offset; 141 const u32 *src = desc->src; 142 int len = desc->len / 4; 143 int i; 144 145 for (i = 0; i < len; i += 2) { 146 dst[i + 1] = swab32(src[i]); 147 dst[i] = swab32(src[i + 1]); 148 } 149} 150 151int coda_jpeg_write_tables(struct coda_ctx *ctx) 152{ 153 int i; 154 static const struct coda_memcpy_desc huff[8] = { 155 { 0, luma_dc_bits, sizeof(luma_dc_bits) }, 156 { 16, luma_dc_value, sizeof(luma_dc_value) }, 157 { 32, luma_ac_bits, sizeof(luma_ac_bits) }, 158 { 48, luma_ac_value, sizeof(luma_ac_value) }, 159 { 216, chroma_dc_bits, sizeof(chroma_dc_bits) }, 160 { 232, chroma_dc_value, sizeof(chroma_dc_value) }, 161 { 248, chroma_ac_bits, sizeof(chroma_ac_bits) }, 162 { 264, chroma_ac_value, sizeof(chroma_ac_value) }, 163 }; 164 struct coda_memcpy_desc qmat[3] = { 165 { 512, ctx->params.jpeg_qmat_tab[0], 64 }, 166 { 576, ctx->params.jpeg_qmat_tab[1], 64 }, 167 { 640, ctx->params.jpeg_qmat_tab[1], 64 }, 168 }; 169 170 /* Write huffman tables to parameter memory */ 171 for (i = 0; i < ARRAY_SIZE(huff); i++) 172 coda_memcpy_parabuf(ctx->parabuf.vaddr, huff + i); 173 174 /* Write Q-matrix to parameter memory */ 175 for (i = 0; i < ARRAY_SIZE(qmat); i++) 176 coda_memcpy_parabuf(ctx->parabuf.vaddr, qmat + i); 177 178 return 0; 179} 180 181bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb) 182{ 183 void *vaddr = vb2_plane_vaddr(vb, 0); 184 u16 soi = be16_to_cpup((__be16 *)vaddr); 185 u16 eoi = be16_to_cpup((__be16 *)(vaddr + 186 vb2_get_plane_payload(vb, 0) - 2)); 187 188 return soi == SOI_MARKER && eoi == EOI_MARKER; 189} 190 191/* 192 * Scale quantization table using nonlinear scaling factor 193 * u8 qtab[64], scale [50,190] 194 */ 195static void coda_scale_quant_table(u8 *q_tab, int scale) 196{ 197 unsigned int temp; 198 int i; 199 200 for (i = 0; i < 64; i++) { 201 temp = DIV_ROUND_CLOSEST((unsigned int)q_tab[i] * scale, 100); 202 if (temp <= 0) 203 temp = 1; 204 if (temp > 255) 205 temp = 255; 206 q_tab[i] = (unsigned char)temp; 207 } 208} 209 210void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality) 211{ 212 unsigned int scale; 213 214 ctx->params.jpeg_quality = quality; 215 216 /* Clip quality setting to [5,100] interval */ 217 if (quality > 100) 218 quality = 100; 219 if (quality < 5) 220 quality = 5; 221 222 /* 223 * Non-linear scaling factor: 224 * [5,50] -> [1000..100], [51,100] -> [98..0] 225 */ 226 if (quality < 50) 227 scale = 5000 / quality; 228 else 229 scale = 200 - 2 * quality; 230 231 if (ctx->params.jpeg_qmat_tab[0]) { 232 memcpy(ctx->params.jpeg_qmat_tab[0], luma_q, 64); 233 coda_scale_quant_table(ctx->params.jpeg_qmat_tab[0], scale); 234 } 235 if (ctx->params.jpeg_qmat_tab[1]) { 236 memcpy(ctx->params.jpeg_qmat_tab[1], chroma_q, 64); 237 coda_scale_quant_table(ctx->params.jpeg_qmat_tab[1], scale); 238 } 239} 240