1 /*
2  *  Copyright (C) 2009 Exult Team
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Library General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Library General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Library General Public
15  *  License along with this library; if not, write to the
16  *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  *  Boston, MA  02111-1307, USA.
18  */
19 
20 #ifndef INCL_SCALE_INTERLACE_H
21 #define INCL_SCALE_INTERLACE_H  1
22 
23 #include "ignore_unused_variable_warning.h"
24 
25 /**
26  ** Note: This file should only be included by source files that use the
27  ** templates below; the templates will only be instantiated when they
28  ** are used anyway.
29  **/
30 
31 //
32 // Interlaced Point Sampling Scaler; adapted from Pentagram.
33 //
34 
35 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
Scale_interlace(Source_pixel * source,int srcx,int srcy,int srcw,int srch,int sline_pixels,int sheight,Dest_pixel * dest,int dline_pixels,const Manip_pixels & manip,const int factor)36 void Scale_interlace(
37     Source_pixel *source,   // ->source pixels.
38     int srcx, int srcy,     // Start of rectangle within src.
39     int srcw, int srch,     // Dims. of rectangle.
40     int sline_pixels,       // Pixels (words)/line for source.
41     int sheight,            // Source height.
42     Dest_pixel *dest,       // ->dest pixels.
43     int dline_pixels,       // Pixels (words)/line for dest.
44     const Manip_pixels &manip,  // Manipulator methods.
45     const int factor        // Scale factor
46 ) {
47 	ignore_unused_variable_warning(sheight);
48 	// Source buffer pointers
49 	Source_pixel *from = source + srcy * sline_pixels + srcx;
50 	Source_pixel *limit_x = from + srcw;
51 	Source_pixel *limit_y = from + srch * sline_pixels;
52 	int sdiff = sline_pixels - srcw;
53 
54 	// Dest buffer pointers
55 	Dest_pixel *to = (dest + factor * srcy * dline_pixels + factor * srcx);
56 
57 	if (factor == 2) {
58 		int pdiff = 2 * dline_pixels - 2 * srcw;
59 		// Src loop Y
60 		do {
61 			// Src loop X
62 			do {
63 				Dest_pixel p = manip.copy(*from++);
64 				*(to + 0) = p;
65 				*(to + 1) = p;
66 				to  += 2;
67 			} while (from != limit_x);
68 			to  += pdiff;
69 
70 			from += sdiff;
71 			limit_x += sline_pixels;
72 		} while (from != limit_y);
73 	} else {
74 		bool visible_line = ((srcy * factor) % 2 == 0);
75 		bool visible_line_inner = visible_line;
76 		Dest_pixel *px_end = to + factor;
77 		Dest_pixel *py_end = to + factor * dline_pixels;
78 
79 		int block_h = dline_pixels * factor;
80 		int block_xdiff = dline_pixels - factor;
81 		int pdiff = block_h - factor * srcw;
82 		// Src loop Y
83 		do {
84 			// Src loop X
85 			do {
86 				visible_line_inner = visible_line;
87 				Dest_pixel p = manip.copy(*from++);
88 				// Inner loops
89 				// Dest loop Y
90 				do {
91 					if (visible_line_inner) {
92 						// Dest loop X
93 						do {
94 							*to++ = p;
95 						} while (to != px_end);
96 					} else
97 						to = px_end;
98 					to  += block_xdiff;
99 					px_end += dline_pixels;
100 					visible_line_inner = !visible_line_inner;
101 				} while (to != py_end);
102 
103 				to  += factor - block_h;
104 				px_end += factor - block_h;
105 				py_end += factor;
106 			} while (from != limit_x);
107 			to  += pdiff;
108 			py_end += pdiff;
109 			px_end += pdiff;
110 
111 			from += sdiff;
112 			limit_x += sline_pixels;
113 			visible_line = visible_line_inner;
114 		} while (from != limit_y);
115 	}
116 }
117 
118 // Interlaced Point Sampling Scaler
119 void Scale_interlace(
120     const unsigned char *source,    // ->source pixels.
121     const int srcx, const int srcy, // Start of rectangle within src.
122     const int srcw, const int srch, // Dims. of rectangle.
123     const int sline_pixels,     // Pixels (words)/line for source.
124     const int sheight,      // Source height.
125     unsigned char *dest,        // ->dest pixels.
126     const int dline_pixels,     // Pixels (words)/line for dest.
127     const int factor        // Scale factor
128 );
129 
130 #endif
131