1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#cython: boundscheck=False
#cython: wraparound=False
from libc.stdlib cimport abs as c_abs
cimport cpython.array
# TODO: I don't know how can I not return any value (void doesn't work)
cpdef int undo_filter_sub(int filter_unit, unsigned char[:] scanline,
unsigned char[:] previous, unsigned char[:] result) nogil:
"""Undo sub filter."""
cdef int l = result.shape[0]
cdef int ai = 0
cdef unsigned char x, a
# Loops starts at index fu. Observe that the initial part
# of the result is already filled in correctly with
# scanline.
for i in range(filter_unit, l):
x = scanline[i]
a = result[ai]
result[i] = (x + a) & 0xff
ai += 1
return 0
cpdef int undo_filter_up(int filter_unit, unsigned char[:] scanline,
unsigned char[:] previous, unsigned char[:] result) nogil:
"""Undo up filter."""
cdef int i
cdef int l = result.shape[0]
cdef unsigned char x, b
for i in range(l):
x = scanline[i]
b = previous[i]
result[i] = (x + b) & 0xff
return 0
cpdef int undo_filter_average(int filter_unit, unsigned char[:] scanline,
unsigned char[:] previous, unsigned char[:] result) nogil:
"""Undo up filter."""
cdef int i, ai
cdef int l = result.shape[0]
cdef unsigned char x, a, b
ai = -filter_unit
for i in range(l):
x = scanline[i]
if ai < 0:
a = 0
else:
a = result[ai]
b = previous[i]
result[i] = (x + ((a + b) >> 1)) & 0xff
ai += 1
return 0
cpdef int undo_filter_paeth(int filter_unit, unsigned char[:] scanline,
unsigned char[:] previous, unsigned char[:] result) nogil:
"""Undo Paeth filter."""
# Also used for ci.
cdef int ai = -filter_unit
cdef int l = result.shape[0]
cdef int i, pa, pb, pc, p
cdef unsigned char x, a, b, c, pr
for i in range(l):
x = scanline[i]
if ai < 0:
a = c = 0
else:
a = result[ai]
c = previous[ai]
b = previous[i]
p = a + b - c
pa = c_abs(p - a)
pb = c_abs(p - b)
pc = c_abs(p - c)
if pa <= pb and pa <= pc:
pr = a
elif pb <= pc:
pr = b
else:
pr = c
result[i] = (x + pr) & 0xff
ai += 1
return 0
cpdef int convert_rgb_to_rgba(unsigned char[:] row, unsigned char[:] result) nogil:
cdef int i, l, j, k
l = min(row.shape[0] / 3, result.shape[0] / 4)
for i in range(l):
j = i * 3
k = i * 4
result[k] = row[j]
result[k + 1] = row[j + 1]
result[k + 2] = row[j + 2]
return 0
cpdef int convert_l_to_rgba(unsigned char[:] row, unsigned char[:] result) nogil:
cdef int i, l, j, k, lum
l = min(row.shape[0], result.shape[0] / 4)
for i in range(l):
j = i
k = i * 4
lum = row[j]
result[k] = lum
result[k + 1] = lum
result[k + 2] = lum
return 0
cpdef int convert_la_to_rgba(unsigned char[:] row, unsigned char[:] result) nogil:
cdef int i, l, j, k, lum
l = min(row.shape[0] / 2, result.shape[0] / 4)
for i in range(l):
j = i * 2
k = i * 4
lum = row[j]
result[k] = lum
result[k + 1] = lum
result[k + 2] = lum
result[k + 3] = row[j + 1]
return 0
|