18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: LGPL-2.1+ */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2016 Tom aan de Wiel 48c2ecf20Sopenharmony_ci * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef CODEC_FWHT_H 88c2ecf20Sopenharmony_ci#define CODEC_FWHT_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/types.h> 118c2ecf20Sopenharmony_ci#include <linux/bitops.h> 128c2ecf20Sopenharmony_ci#include <asm/byteorder.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* 158c2ecf20Sopenharmony_ci * The compressed format consists of a fwht_cframe_hdr struct followed by the 168c2ecf20Sopenharmony_ci * compressed frame data. The header contains the size of that data. 178c2ecf20Sopenharmony_ci * Each Y, Cb and Cr plane is compressed separately. If the compressed 188c2ecf20Sopenharmony_ci * size of each plane becomes larger than the uncompressed size, then 198c2ecf20Sopenharmony_ci * that plane is stored uncompressed and the corresponding bit is set 208c2ecf20Sopenharmony_ci * in the flags field of the header. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * Each compressed plane consists of macroblocks and each macroblock 238c2ecf20Sopenharmony_ci * is run-length-encoded. Each macroblock starts with a 16 bit value. 248c2ecf20Sopenharmony_ci * Bit 15 indicates if this is a P-coded macroblock (1) or not (0). 258c2ecf20Sopenharmony_ci * P-coded macroblocks contain a delta against the previous frame. 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * Bits 1-12 contain a number. If non-zero, then this same macroblock 288c2ecf20Sopenharmony_ci * repeats that number of times. This results in a high degree of 298c2ecf20Sopenharmony_ci * compression for generated images like colorbars. 308c2ecf20Sopenharmony_ci * 318c2ecf20Sopenharmony_ci * Following this macroblock header the MB coefficients are run-length 328c2ecf20Sopenharmony_ci * encoded: the top 12 bits contain the coefficient, the bottom 4 bits 338c2ecf20Sopenharmony_ci * tell how many times this coefficient occurs. The value 0xf indicates 348c2ecf20Sopenharmony_ci * that the remainder of the macroblock should be filled with zeroes. 358c2ecf20Sopenharmony_ci * 368c2ecf20Sopenharmony_ci * All 16 and 32 bit values are stored in big-endian (network) order. 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * Each fwht_cframe_hdr starts with an 8 byte magic header that is 398c2ecf20Sopenharmony_ci * guaranteed not to occur in the compressed frame data. This header 408c2ecf20Sopenharmony_ci * can be used to sync to the next frame. 418c2ecf20Sopenharmony_ci * 428c2ecf20Sopenharmony_ci * This codec uses the Fast Walsh Hadamard Transform. Tom aan de Wiel 438c2ecf20Sopenharmony_ci * developed this as part of a university project, specifically for use 448c2ecf20Sopenharmony_ci * with this driver. His project report can be found here: 458c2ecf20Sopenharmony_ci * 468c2ecf20Sopenharmony_ci * https://hverkuil.home.xs4all.nl/fwht.pdf 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci/* 508c2ecf20Sopenharmony_ci * This is a sequence of 8 bytes with the low 4 bits set to 0xf. 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci * This sequence cannot occur in the encoded data 538c2ecf20Sopenharmony_ci * 548c2ecf20Sopenharmony_ci * Note that these two magic values are symmetrical so endian issues here. 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_ci#define FWHT_MAGIC1 0x4f4f4f4f 578c2ecf20Sopenharmony_ci#define FWHT_MAGIC2 0xffffffff 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define FWHT_VERSION 3 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* Set if this is an interlaced format */ 628c2ecf20Sopenharmony_ci#define FWHT_FL_IS_INTERLACED BIT(0) 638c2ecf20Sopenharmony_ci/* Set if this is a bottom-first (NTSC) interlaced format */ 648c2ecf20Sopenharmony_ci#define FWHT_FL_IS_BOTTOM_FIRST BIT(1) 658c2ecf20Sopenharmony_ci/* Set if each 'frame' contains just one field */ 668c2ecf20Sopenharmony_ci#define FWHT_FL_IS_ALTERNATE BIT(2) 678c2ecf20Sopenharmony_ci/* 688c2ecf20Sopenharmony_ci * If FWHT_FL_IS_ALTERNATE was set, then this is set if this 698c2ecf20Sopenharmony_ci * 'frame' is the bottom field, else it is the top field. 708c2ecf20Sopenharmony_ci */ 718c2ecf20Sopenharmony_ci#define FWHT_FL_IS_BOTTOM_FIELD BIT(3) 728c2ecf20Sopenharmony_ci/* Set if this frame is uncompressed */ 738c2ecf20Sopenharmony_ci#define FWHT_FL_LUMA_IS_UNCOMPRESSED BIT(4) 748c2ecf20Sopenharmony_ci#define FWHT_FL_CB_IS_UNCOMPRESSED BIT(5) 758c2ecf20Sopenharmony_ci#define FWHT_FL_CR_IS_UNCOMPRESSED BIT(6) 768c2ecf20Sopenharmony_ci#define FWHT_FL_CHROMA_FULL_HEIGHT BIT(7) 778c2ecf20Sopenharmony_ci#define FWHT_FL_CHROMA_FULL_WIDTH BIT(8) 788c2ecf20Sopenharmony_ci#define FWHT_FL_ALPHA_IS_UNCOMPRESSED BIT(9) 798c2ecf20Sopenharmony_ci#define FWHT_FL_I_FRAME BIT(10) 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci/* A 4-values flag - the number of components - 1 */ 828c2ecf20Sopenharmony_ci#define FWHT_FL_COMPONENTS_NUM_MSK GENMASK(18, 16) 838c2ecf20Sopenharmony_ci#define FWHT_FL_COMPONENTS_NUM_OFFSET 16 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci#define FWHT_FL_PIXENC_MSK GENMASK(20, 19) 868c2ecf20Sopenharmony_ci#define FWHT_FL_PIXENC_OFFSET 19 878c2ecf20Sopenharmony_ci#define FWHT_FL_PIXENC_YUV (1 << FWHT_FL_PIXENC_OFFSET) 888c2ecf20Sopenharmony_ci#define FWHT_FL_PIXENC_RGB (2 << FWHT_FL_PIXENC_OFFSET) 898c2ecf20Sopenharmony_ci#define FWHT_FL_PIXENC_HSV (3 << FWHT_FL_PIXENC_OFFSET) 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci/* 928c2ecf20Sopenharmony_ci * A macro to calculate the needed padding in order to make sure 938c2ecf20Sopenharmony_ci * both luma and chroma components resolutions are rounded up to 948c2ecf20Sopenharmony_ci * a multiple of 8 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_ci#define vic_round_dim(dim, div) (round_up((dim) / (div), 8) * (div)) 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistruct fwht_cframe_hdr { 998c2ecf20Sopenharmony_ci u32 magic1; 1008c2ecf20Sopenharmony_ci u32 magic2; 1018c2ecf20Sopenharmony_ci __be32 version; 1028c2ecf20Sopenharmony_ci __be32 width, height; 1038c2ecf20Sopenharmony_ci __be32 flags; 1048c2ecf20Sopenharmony_ci __be32 colorspace; 1058c2ecf20Sopenharmony_ci __be32 xfer_func; 1068c2ecf20Sopenharmony_ci __be32 ycbcr_enc; 1078c2ecf20Sopenharmony_ci __be32 quantization; 1088c2ecf20Sopenharmony_ci __be32 size; 1098c2ecf20Sopenharmony_ci}; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistruct fwht_cframe { 1128c2ecf20Sopenharmony_ci u16 i_frame_qp; 1138c2ecf20Sopenharmony_ci u16 p_frame_qp; 1148c2ecf20Sopenharmony_ci __be16 *rlc_data; 1158c2ecf20Sopenharmony_ci s16 coeffs[8 * 8]; 1168c2ecf20Sopenharmony_ci s16 de_coeffs[8 * 8]; 1178c2ecf20Sopenharmony_ci s16 de_fwht[8 * 8]; 1188c2ecf20Sopenharmony_ci u32 size; 1198c2ecf20Sopenharmony_ci}; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistruct fwht_raw_frame { 1228c2ecf20Sopenharmony_ci unsigned int width_div; 1238c2ecf20Sopenharmony_ci unsigned int height_div; 1248c2ecf20Sopenharmony_ci unsigned int luma_alpha_step; 1258c2ecf20Sopenharmony_ci unsigned int chroma_step; 1268c2ecf20Sopenharmony_ci unsigned int components_num; 1278c2ecf20Sopenharmony_ci u8 *buf; 1288c2ecf20Sopenharmony_ci u8 *luma, *cb, *cr, *alpha; 1298c2ecf20Sopenharmony_ci}; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci#define FWHT_FRAME_PCODED BIT(0) 1328c2ecf20Sopenharmony_ci#define FWHT_FRAME_UNENCODED BIT(1) 1338c2ecf20Sopenharmony_ci#define FWHT_LUMA_UNENCODED BIT(2) 1348c2ecf20Sopenharmony_ci#define FWHT_CB_UNENCODED BIT(3) 1358c2ecf20Sopenharmony_ci#define FWHT_CR_UNENCODED BIT(4) 1368c2ecf20Sopenharmony_ci#define FWHT_ALPHA_UNENCODED BIT(5) 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ciu32 fwht_encode_frame(struct fwht_raw_frame *frm, 1398c2ecf20Sopenharmony_ci struct fwht_raw_frame *ref_frm, 1408c2ecf20Sopenharmony_ci struct fwht_cframe *cf, 1418c2ecf20Sopenharmony_ci bool is_intra, bool next_is_intra, 1428c2ecf20Sopenharmony_ci unsigned int width, unsigned int height, 1438c2ecf20Sopenharmony_ci unsigned int stride, unsigned int chroma_stride); 1448c2ecf20Sopenharmony_cibool fwht_decode_frame(struct fwht_cframe *cf, u32 hdr_flags, 1458c2ecf20Sopenharmony_ci unsigned int components_num, unsigned int width, 1468c2ecf20Sopenharmony_ci unsigned int height, const struct fwht_raw_frame *ref, 1478c2ecf20Sopenharmony_ci unsigned int ref_stride, unsigned int ref_chroma_stride, 1488c2ecf20Sopenharmony_ci struct fwht_raw_frame *dst, unsigned int dst_stride, 1498c2ecf20Sopenharmony_ci unsigned int dst_chroma_stride); 1508c2ecf20Sopenharmony_ci#endif 151