Blame view
drivers/video/c2p_planar.c
3.61 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * Fast C2P (Chunky-to-Planar) Conversion * |
1f034456c fbdev: c2p - Clea... |
4 |
* Copyright (C) 2003-2008 Geert Uytterhoeven |
1da177e4c Linux-2.6.12-rc2 |
5 |
* |
1da177e4c Linux-2.6.12-rc2 |
6 7 8 9 |
* This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. */ |
8b54b6135 drivers/video/c2p... |
10 |
#include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
11 |
#include <linux/string.h> |
1f034456c fbdev: c2p - Clea... |
12 13 |
#include <asm/unaligned.h> |
1da177e4c Linux-2.6.12-rc2 |
14 |
#include "c2p.h" |
2cd1de0a0 fbdev: c2p - Extr... |
15 |
#include "c2p_core.h" |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 19 20 21 |
/* * Perform a full C2P step on 32 8-bit pixels, stored in 8 32-bit words * containing * - 32 8-bit chunky pixels on input |
1f034456c fbdev: c2p - Clea... |
22 |
* - permutated planar data (1 plane per 32-bit word) on output |
1da177e4c Linux-2.6.12-rc2 |
23 |
*/ |
1f034456c fbdev: c2p - Clea... |
24 |
static void c2p_32x8(u32 d[8]) |
1da177e4c Linux-2.6.12-rc2 |
25 |
{ |
1f034456c fbdev: c2p - Clea... |
26 27 28 29 30 |
transp8(d, 16, 4); transp8(d, 8, 2); transp8(d, 4, 1); transp8(d, 2, 4); transp8(d, 1, 2); |
1da177e4c Linux-2.6.12-rc2 |
31 32 33 34 |
} /* |
1f034456c fbdev: c2p - Clea... |
35 |
* Array containing the permutation indices of the planar data after c2p |
1da177e4c Linux-2.6.12-rc2 |
36 |
*/ |
1f034456c fbdev: c2p - Clea... |
37 |
static const int perm_c2p_32x8[8] = { 7, 5, 3, 1, 6, 4, 2, 0 }; |
1da177e4c Linux-2.6.12-rc2 |
38 39 40 |
/* |
1da177e4c Linux-2.6.12-rc2 |
41 42 |
* Store a full block of planar data after c2p conversion */ |
1f034456c fbdev: c2p - Clea... |
43 |
static inline void store_planar(void *dst, u32 dst_inc, u32 bpp, u32 d[8]) |
1da177e4c Linux-2.6.12-rc2 |
44 |
{ |
8280eb8a3 fbdev: c2p - Corr... |
45 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
46 |
|
8280eb8a3 fbdev: c2p - Corr... |
47 |
for (i = 0; i < bpp; i++, dst += dst_inc) |
1f034456c fbdev: c2p - Clea... |
48 |
put_unaligned_be32(d[perm_c2p_32x8[i]], dst); |
1da177e4c Linux-2.6.12-rc2 |
49 50 51 52 53 54 |
} /* * Store a partial block of planar data after c2p conversion */ |
1f034456c fbdev: c2p - Clea... |
55 |
static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp, |
1da177e4c Linux-2.6.12-rc2 |
56 57 |
u32 d[8], u32 mask) { |
8280eb8a3 fbdev: c2p - Corr... |
58 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
59 |
|
8280eb8a3 fbdev: c2p - Corr... |
60 |
for (i = 0; i < bpp; i++, dst += dst_inc) |
1f034456c fbdev: c2p - Clea... |
61 62 63 |
put_unaligned_be32(comp(d[perm_c2p_32x8[i]], get_unaligned_be32(dst), mask), dst); |
1da177e4c Linux-2.6.12-rc2 |
64 65 66 67 |
} /* |
2eab7ff84 fbdev: c2p - Rena... |
68 |
* c2p_planar - Copy 8-bit chunky image data to a planar frame buffer |
1da177e4c Linux-2.6.12-rc2 |
69 70 71 72 73 74 75 76 77 78 |
* @dst: Starting address of the planar frame buffer * @dx: Horizontal destination offset (in pixels) * @dy: Vertical destination offset (in pixels) * @width: Image width (in pixels) * @height: Image height (in pixels) * @dst_nextline: Frame buffer offset to the next line (in bytes) * @dst_nextplane: Frame buffer offset to the next plane (in bytes) * @src_nextline: Image offset to the next line (in bytes) * @bpp: Bits per pixel of the planar frame buffer (1-8) */ |
2eab7ff84 fbdev: c2p - Rena... |
79 80 81 |
void c2p_planar(void *dst, const void *src, u32 dx, u32 dy, u32 width, u32 height, u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp) |
1da177e4c Linux-2.6.12-rc2 |
82 |
{ |
1f034456c fbdev: c2p - Clea... |
83 84 85 86 87 |
union { u8 pixels[32]; u32 words[8]; } d; u32 dst_idx, first, last, w; |
8280eb8a3 fbdev: c2p - Corr... |
88 |
const u8 *c; |
1f034456c fbdev: c2p - Clea... |
89 |
void *p; |
8280eb8a3 fbdev: c2p - Corr... |
90 91 92 |
dst += dy*dst_nextline+(dx & ~31); dst_idx = dx % 32; |
1f034456c fbdev: c2p - Clea... |
93 94 |
first = 0xffffffffU >> dst_idx; last = ~(0xffffffffU >> ((dst_idx+width) % 32)); |
8280eb8a3 fbdev: c2p - Corr... |
95 96 97 98 99 100 101 |
while (height--) { c = src; p = dst; w = width; if (dst_idx+width <= 32) { /* Single destination word */ first &= last; |
1f034456c fbdev: c2p - Clea... |
102 103 |
memset(d.pixels, 0, sizeof(d)); memcpy(d.pixels+dst_idx, c, width); |
8280eb8a3 fbdev: c2p - Corr... |
104 |
c += width; |
1f034456c fbdev: c2p - Clea... |
105 106 107 |
c2p_32x8(d.words); store_planar_masked(p, dst_nextplane, bpp, d.words, first); |
8280eb8a3 fbdev: c2p - Corr... |
108 109 110 111 112 113 114 |
p += 4; } else { /* Multiple destination words */ w = width; /* Leading bits */ if (dst_idx) { w = 32 - dst_idx; |
1f034456c fbdev: c2p - Clea... |
115 116 |
memset(d.pixels, 0, dst_idx); memcpy(d.pixels+dst_idx, c, w); |
8280eb8a3 fbdev: c2p - Corr... |
117 |
c += w; |
1f034456c fbdev: c2p - Clea... |
118 119 120 |
c2p_32x8(d.words); store_planar_masked(p, dst_nextplane, bpp, d.words, first); |
8280eb8a3 fbdev: c2p - Corr... |
121 122 123 124 125 |
p += 4; w = width-w; } /* Main chunk */ while (w >= 32) { |
1f034456c fbdev: c2p - Clea... |
126 |
memcpy(d.pixels, c, 32); |
8280eb8a3 fbdev: c2p - Corr... |
127 |
c += 32; |
1f034456c fbdev: c2p - Clea... |
128 129 |
c2p_32x8(d.words); store_planar(p, dst_nextplane, bpp, d.words); |
8280eb8a3 fbdev: c2p - Corr... |
130 131 132 133 134 135 |
p += 4; w -= 32; } /* Trailing bits */ w %= 32; if (w > 0) { |
1f034456c fbdev: c2p - Clea... |
136 137 138 139 140 |
memcpy(d.pixels, c, w); memset(d.pixels+w, 0, 32-w); c2p_32x8(d.words); store_planar_masked(p, dst_nextplane, bpp, d.words, last); |
8280eb8a3 fbdev: c2p - Corr... |
141 142 143 144 |
} } src += src_nextline; dst += dst_nextline; |
1da177e4c Linux-2.6.12-rc2 |
145 |
} |
1da177e4c Linux-2.6.12-rc2 |
146 |
} |
2eab7ff84 fbdev: c2p - Rena... |
147 |
EXPORT_SYMBOL_GPL(c2p_planar); |
1da177e4c Linux-2.6.12-rc2 |
148 |
|
8b54b6135 drivers/video/c2p... |
149 |
MODULE_LICENSE("GPL"); |