|
|
1.1 root 1: /*
2: * This file is part of the Scale2x project.
3: *
4: * Copyright (C) 2001-2003 Andrea Mazzoleni
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: * This program is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: * GNU General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with this program; if not, write to the Free Software
18: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19: */
20:
21: /*
22: * This file contains a fast C implementation of the Scale3x effect.
23: *
24: * You can find an high level description of the effect at :
25: *
26: * http://scale2x.sourceforge.net/
27: *
28: * Alternatively at the previous license terms, you are allowed to use this
29: * code in your program with these conditions:
30: * - the program is not used in commercial activities.
31: * - the whole source code of the program is released with the binary.
32: * - derivative works of the program are allowed.
33: */
34:
35: #ifndef __SCALE3X_H
36: #define __SCALE3X_H
37:
38: #include <assert.h>
39:
40: /***************************************************************************/
41: /* Basic types */
42:
43: typedef unsigned char scale3x_uint8;
44: typedef unsigned short scale3x_uint16;
45: typedef unsigned scale3x_uint32;
46:
47: /***************************************************************************/
48: /* Scale3x C implementation */
49:
50: static void scale3x_8_def_single(scale3x_uint8* dst, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
51: {
52: assert(count >= 2);
53:
54: /* first pixel */
55: dst[0] = src1[0];
56: dst[1] = src1[0];
57: if (src1[1] == src0[0] && src2[0] != src0[0])
58: dst[2] = src0[0];
59: else
60: dst[2] = src1[0];
61: ++src0;
62: ++src1;
63: ++src2;
64: dst += 3;
65:
66: /* central pixels */
67: count -= 2;
68: while (count) {
69: if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0])
70: dst[0] = src0[0];
71: else
72: dst[0] = src1[0];
73: dst[1] = src1[0];
74: if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0])
75: dst[2] = src0[0];
76: else
77: dst[2] = src1[0];
78:
79: ++src0;
80: ++src1;
81: ++src2;
82:
83: dst += 3;
84: --count;
85: }
86:
87: /* last pixel */
88: if (src1[-1] == src0[0] && src2[0] != src0[0])
89: dst[0] = src0[0];
90: else
91: dst[0] = src1[0];
92: dst[1] = src1[0];
93: dst[2] = src1[0];
94: }
95:
96: static void scale3x_8_def_fill(scale3x_uint8* dst, const scale3x_uint8* src, unsigned count)
97: {
98: while (count) {
99: dst[0] = src[0];
100: dst[1] = src[0];
101: dst[2] = src[0];
102:
103: ++src;
104: dst += 3;
105: --count;
106: }
107: }
108:
109: static void scale3x_16_def_single(scale3x_uint16* dst, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
110: {
111: assert(count >= 2);
112:
113: /* first pixel */
114: dst[0] = src1[0];
115: dst[1] = src1[0];
116: if (src1[1] == src0[0] && src2[0] != src0[0])
117: dst[2] = src0[0];
118: else
119: dst[2] = src1[0];
120: ++src0;
121: ++src1;
122: ++src2;
123: dst += 3;
124:
125: /* central pixels */
126: count -= 2;
127: while (count) {
128: if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0])
129: dst[0] = src0[0];
130: else
131: dst[0] = src1[0];
132: dst[1] = src1[0];
133: if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0])
134: dst[2] = src0[0];
135: else
136: dst[2] = src1[0];
137:
138: ++src0;
139: ++src1;
140: ++src2;
141:
142: dst += 3;
143: --count;
144: }
145:
146: /* last pixel */
147: if (src1[-1] == src0[0] && src2[0] != src0[0])
148: dst[0] = src0[0];
149: else
150: dst[0] = src1[0];
151: dst[1] = src1[0];
152: dst[2] = src1[0];
153: }
154:
155: static void scale3x_16_def_fill(scale3x_uint16* dst, const scale3x_uint16* src, unsigned count)
156: {
157: while (count) {
158: dst[0] = src[0];
159: dst[1] = src[0];
160: dst[2] = src[0];
161:
162: ++src;
163: dst += 3;
164: --count;
165: }
166: }
167:
168: static void scale3x_32_def_single(scale3x_uint32* dst, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
169: {
170: assert(count >= 2);
171:
172: /* first pixel */
173: dst[0] = src1[0];
174: dst[1] = src1[0];
175: if (src1[1] == src0[0] && src2[0] != src0[0])
176: dst[2] = src0[0];
177: else
178: dst[2] = src1[0];
179: ++src0;
180: ++src1;
181: ++src2;
182: dst += 3;
183:
184: /* central pixels */
185: count -= 2;
186: while (count) {
187: if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0])
188: dst[0] = src0[0];
189: else
190: dst[0] = src1[0];
191: dst[1] = src1[0];
192: if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0])
193: dst[2] = src0[0];
194: else
195: dst[2] = src1[0];
196:
197: ++src0;
198: ++src1;
199: ++src2;
200:
201: dst += 3;
202: --count;
203: }
204:
205: /* last pixel */
206: if (src1[-1] == src0[0] && src2[0] != src0[0])
207: dst[0] = src0[0];
208: else
209: dst[0] = src1[0];
210: dst[1] = src1[0];
211: dst[2] = src1[0];
212: }
213:
214: static void scale3x_32_def_fill(scale3x_uint32* dst, const scale3x_uint32* src, unsigned count)
215: {
216: while (count) {
217: dst[0] = src[0];
218: dst[1] = src[0];
219: dst[2] = src[0];
220:
221: ++src;
222: dst += 3;
223: --count;
224: }
225: }
226:
227: /**
228: * Scale by a factor of 3 a row of pixels of 8 bits.
229: * The function is implemented in C.
230: * The pixels over the left and right borders are assumed of the same color of
231: * the pixels on the border.
232: * \param src0 Pointer at the first pixel of the previous row.
233: * \param src1 Pointer at the first pixel of the current row.
234: * \param src2 Pointer at the first pixel of the next row.
235: * \param count Length in pixels of the src0, src1 and src2 rows.
236: * It must be at least 2.
237: * \param dst0 First destination row, triple length in pixels.
238: * \param dst1 Second destination row, triple length in pixels.
239: * \param dst2 Third destination row, triple length in pixels.
240: */
241: static inline void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
242: {
243: assert(count >= 2);
244:
245: scale3x_8_def_single(dst0, src0, src1, src2, count);
246: scale3x_8_def_fill(dst1, src1, count);
247: scale3x_8_def_single(dst2, src2, src1, src0, count);
248: }
249:
250: /**
251: * Scale by a factor of 3 a row of pixels of 16 bits.
252: * This function operates like scale3x_8_def() but for 16 bits pixels.
253: * \param src0 Pointer at the first pixel of the previous row.
254: * \param src1 Pointer at the first pixel of the current row.
255: * \param src2 Pointer at the first pixel of the next row.
256: * \param count Length in pixels of the src0, src1 and src2 rows.
257: * It must be at least 2.
258: * \param dst0 First destination row, triple length in pixels.
259: * \param dst1 Second destination row, triple length in pixels.
260: * \param dst2 Third destination row, triple length in pixels.
261: */
262: static inline void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
263: {
264: assert(count >= 2);
265:
266: scale3x_16_def_single(dst0, src0, src1, src2, count);
267: scale3x_16_def_fill(dst1, src1, count);
268: scale3x_16_def_single(dst2, src2, src1, src0, count);
269: }
270:
271: /**
272: * Scale by a factor of 3 a row of pixels of 32 bits.
273: * This function operates like scale3x_8_def() but for 32 bits pixels.
274: * \param src0 Pointer at the first pixel of the previous row.
275: * \param src1 Pointer at the first pixel of the current row.
276: * \param src2 Pointer at the first pixel of the next row.
277: * \param count Length in pixels of the src0, src1 and src2 rows.
278: * It must be at least 2.
279: * \param dst0 First destination row, triple length in pixels.
280: * \param dst1 Second destination row, triple length in pixels.
281: * \param dst2 Third destination row, triple length in pixels.
282: */
283: static inline void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
284: {
285: assert(count >= 2);
286:
287: scale3x_32_def_single(dst0, src0, src1, src2, count);
288: scale3x_32_def_fill(dst1, src1, count);
289: scale3x_32_def_single(dst2, src2, src1, src0, count);
290: }
291:
292: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.