root/drivers/staging/media/hantro/hantro_jpeg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. jpeg_scale_quant_table
  2. jpeg_set_quality
  3. hantro_jpeg_get_qtable
  4. hantro_jpeg_header_assemble
  5. hantro_jpeg_enc_init
  6. hantro_jpeg_enc_exit

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * Copyright (C) Collabora, Ltd.
   4  *
   5  * Based on GSPCA and CODA drivers:
   6  * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
   7  * Copyright (C) 2014 Philipp Zabel, Pengutronix
   8  */
   9 #include <linux/dma-mapping.h>
  10 #include <linux/kernel.h>
  11 #include <linux/string.h>
  12 #include "hantro_jpeg.h"
  13 #include "hantro.h"
  14 
  15 #define LUMA_QUANT_OFF          7
  16 #define CHROMA_QUANT_OFF        72
  17 #define HEIGHT_OFF              141
  18 #define WIDTH_OFF               143
  19 
  20 #define HUFF_LUMA_DC_OFF        160
  21 #define HUFF_LUMA_AC_OFF        193
  22 #define HUFF_CHROMA_DC_OFF      376
  23 #define HUFF_CHROMA_AC_OFF      409
  24 
  25 /* Default tables from JPEG ITU-T.81
  26  * (ISO/IEC 10918-1) Annex K.3, I
  27  */
  28 static const unsigned char luma_q_table[] = {
  29         0x10, 0x0b, 0x0a, 0x10, 0x7c, 0x8c, 0x97, 0xa1,
  30         0x0c, 0x0c, 0x0e, 0x13, 0x7e, 0x9e, 0xa0, 0x9b,
  31         0x0e, 0x0d, 0x10, 0x18, 0x8c, 0x9d, 0xa9, 0x9c,
  32         0x0e, 0x11, 0x16, 0x1d, 0x97, 0xbb, 0xb4, 0xa2,
  33         0x12, 0x16, 0x25, 0x38, 0xa8, 0x6d, 0x67, 0xb1,
  34         0x18, 0x23, 0x37, 0x40, 0xb5, 0x68, 0x71, 0xc0,
  35         0x31, 0x40, 0x4e, 0x57, 0x67, 0x79, 0x78, 0x65,
  36         0x48, 0x5c, 0x5f, 0x62, 0x70, 0x64, 0x67, 0xc7,
  37 };
  38 
  39 static const unsigned char chroma_q_table[] = {
  40         0x11, 0x12, 0x18, 0x2f, 0x63, 0x63, 0x63, 0x63,
  41         0x12, 0x15, 0x1a, 0x42, 0x63, 0x63, 0x63, 0x63,
  42         0x18, 0x1a, 0x38, 0x63, 0x63, 0x63, 0x63, 0x63,
  43         0x2f, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
  44         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
  45         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
  46         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
  47         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
  48 };
  49 
  50 /* Huffman tables are shared with CODA */
  51 static const unsigned char luma_dc_table[] = {
  52         0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
  53         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  54         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  55         0x08, 0x09, 0x0a, 0x0b,
  56 };
  57 
  58 static const unsigned char chroma_dc_table[] = {
  59         0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  60         0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  61         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  62         0x08, 0x09, 0x0a, 0x0b,
  63 };
  64 
  65 static const unsigned char luma_ac_table[] = {
  66         0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
  67         0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
  68         0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
  69         0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
  70         0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
  71         0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
  72         0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
  73         0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
  74         0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
  75         0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
  76         0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
  77         0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
  78         0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
  79         0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
  80         0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
  81         0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  82         0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
  83         0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
  84         0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
  85         0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
  86         0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
  87         0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
  88         0xf9, 0xfa,
  89 };
  90 
  91 static const unsigned char chroma_ac_table[] = {
  92         0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
  93         0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
  94         0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
  95         0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
  96         0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
  97         0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
  98         0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
  99         0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
 100         0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
 101         0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
 102         0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
 103         0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
 104         0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
 105         0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
 106         0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
 107         0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
 108         0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
 109         0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
 110         0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
 111         0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
 112         0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
 113         0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
 114         0xf9, 0xfa,
 115 };
 116 
 117 /* For simplicity, we keep a pre-formatted JPEG header,
 118  * and we'll use fixed offsets to change the width, height
 119  * quantization tables, etc.
 120  */
 121 static const unsigned char hantro_jpeg_header[JPEG_HEADER_SIZE] = {
 122         /* SOI */
 123         0xff, 0xd8,
 124 
 125         /* DQT */
 126         0xff, 0xdb, 0x00, 0x84,
 127 
 128         0x00,
 129         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 130         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 131         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 132         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 133         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 134         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 135         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 136         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 137 
 138         0x01,
 139         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 140         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 141         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 142         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 143         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 144         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 145         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 146         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 147 
 148         /* SOF */
 149         0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x01,
 150         0x40, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01,
 151         0x03, 0x11, 0x01,
 152 
 153         /* DHT */
 154         0xff, 0xc4, 0x00, 0x1f, 0x00,
 155 
 156         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 157         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 158         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 159         0x00, 0x00, 0x00, 0x00,
 160 
 161         /* DHT */
 162         0xff, 0xc4, 0x00, 0xb5, 0x10,
 163 
 164         0x00, 0x00,
 165         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 166         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 167         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 168         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 169         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 170         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 171         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 172         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 173         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 174         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 175         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 176         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 177         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 178         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 179         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 180         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 181         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 182         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 183         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 184         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 185         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 186         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 187 
 188         /* DHT */
 189         0xff, 0xc4, 0x00, 0x1f, 0x01,
 190 
 191         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 192         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 193         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 194         0x00, 0x00, 0x00, 0x00,
 195 
 196         /* DHT */
 197         0xff, 0xc4, 0x00, 0xb5, 0x11,
 198 
 199         0x00, 0x00,
 200         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 201         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 202         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 203         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 204         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 205         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 206         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 207         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 208         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 209         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 210         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 211         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 212         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 213         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 214         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 215         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 216         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 217         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 218         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 219         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 220         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 221         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 222 
 223         /* SOS */
 224         0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
 225         0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,
 226 };
 227 
 228 static void
 229 jpeg_scale_quant_table(unsigned char *q_tab,
 230                        const unsigned char *tab, int scale)
 231 {
 232         unsigned int temp;
 233         int i;
 234 
 235         for (i = 0; i < 64; i++) {
 236                 temp = DIV_ROUND_CLOSEST((unsigned int)tab[i] * scale, 100);
 237                 if (temp <= 0)
 238                         temp = 1;
 239                 if (temp > 255)
 240                         temp = 255;
 241                 q_tab[i] = (unsigned char)temp;
 242         }
 243 }
 244 
 245 static void jpeg_set_quality(unsigned char *buffer, int quality)
 246 {
 247         int scale;
 248 
 249         /*
 250          * Non-linear scaling factor:
 251          * [5,50] -> [1000..100], [51,100] -> [98..0]
 252          */
 253         if (quality < 50)
 254                 scale = 5000 / quality;
 255         else
 256                 scale = 200 - 2 * quality;
 257 
 258         jpeg_scale_quant_table(buffer + LUMA_QUANT_OFF,
 259                                luma_q_table, scale);
 260         jpeg_scale_quant_table(buffer + CHROMA_QUANT_OFF,
 261                                chroma_q_table, scale);
 262 }
 263 
 264 unsigned char *
 265 hantro_jpeg_get_qtable(struct hantro_jpeg_ctx *ctx, int index)
 266 {
 267         if (index == 0)
 268                 return ctx->buffer + LUMA_QUANT_OFF;
 269         return ctx->buffer + CHROMA_QUANT_OFF;
 270 }
 271 
 272 void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx)
 273 {
 274         char *buf = ctx->buffer;
 275 
 276         memcpy(buf, hantro_jpeg_header,
 277                sizeof(hantro_jpeg_header));
 278 
 279         buf[HEIGHT_OFF + 0] = ctx->height >> 8;
 280         buf[HEIGHT_OFF + 1] = ctx->height;
 281         buf[WIDTH_OFF + 0] = ctx->width >> 8;
 282         buf[WIDTH_OFF + 1] = ctx->width;
 283 
 284         memcpy(buf + HUFF_LUMA_DC_OFF, luma_dc_table, sizeof(luma_dc_table));
 285         memcpy(buf + HUFF_LUMA_AC_OFF, luma_ac_table, sizeof(luma_ac_table));
 286         memcpy(buf + HUFF_CHROMA_DC_OFF, chroma_dc_table,
 287                sizeof(chroma_dc_table));
 288         memcpy(buf + HUFF_CHROMA_AC_OFF, chroma_ac_table,
 289                sizeof(chroma_ac_table));
 290 
 291         jpeg_set_quality(buf, ctx->quality);
 292 }
 293 
 294 int hantro_jpeg_enc_init(struct hantro_ctx *ctx)
 295 {
 296         ctx->jpeg_enc.bounce_buffer.size =
 297                 ctx->dst_fmt.plane_fmt[0].sizeimage -
 298                 ctx->vpu_dst_fmt->header_size;
 299 
 300         ctx->jpeg_enc.bounce_buffer.cpu =
 301                 dma_alloc_attrs(ctx->dev->dev,
 302                                 ctx->jpeg_enc.bounce_buffer.size,
 303                                 &ctx->jpeg_enc.bounce_buffer.dma,
 304                                 GFP_KERNEL,
 305                                 DMA_ATTR_ALLOC_SINGLE_PAGES);
 306         if (!ctx->jpeg_enc.bounce_buffer.cpu)
 307                 return -ENOMEM;
 308 
 309         return 0;
 310 }
 311 
 312 void hantro_jpeg_enc_exit(struct hantro_ctx *ctx)
 313 {
 314         dma_free_attrs(ctx->dev->dev,
 315                        ctx->jpeg_enc.bounce_buffer.size,
 316                        ctx->jpeg_enc.bounce_buffer.cpu,
 317                        ctx->jpeg_enc.bounce_buffer.dma,
 318                        DMA_ATTR_ALLOC_SINGLE_PAGES);
 319 }

/* [<][>][^][v][top][bottom][index][help] */