4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "downsampleengine.h"
31 DownSamplePackage::DownSamplePackage()
39 DownSampleUnit::DownSampleUnit(DownSampleServer *server)
42 this->server = server;
47 #define DOWNSAMPLE(type, temp_type, components, max) \
53 int do_r = server->r; \
54 int do_g = server->g; \
55 int do_b = server->b; \
56 int do_a = server->a; \
57 type **in_rows = (type**)server->input->get_rows(); \
58 type **out_rows = (type**)server->output->get_rows(); \
60 for(int i = pkg->y1; i < pkg->y2; i += server->vertical) \
63 int y2 = MIN(i + server->vertical, h); \
66 for(int j = server->horizontal_x - server->horizontal; \
68 j += server->horizontal) \
71 int x2 = MIN(j + server->horizontal, w); \
73 temp_type scale = (x2 - x1) * (y2 - y1); \
74 if(x2 > x1 && y2 > y1) \
77 /* Read in values */ \
81 if(components == 4) a = 0; \
83 for(int k = y1; k < y2; k++) \
85 type *row = in_rows[k] + x1 * components; \
86 for(int l = x1; l < x2; l++) \
88 if(do_r) r += *row++; else row++; \
89 if(do_g) g += *row++; else row++; \
90 if(do_b) b += *row++; else row++; \
103 if(components == 4) a /= scale; \
104 for(int k = y1; k < y2; k++) \
106 type *row = out_rows[k] + x1 * components; \
107 for(int l = x1; l < x2; l++) \
109 if(do_r) *row++ = r; else row++; \
110 if(do_g) *row++ = g; else row++; \
111 if(do_b) *row++ = b; else row++; \
112 if(components == 4) \
121 /*printf("DOWNSAMPLE 3 %d\n", i);*/ \
125 void DownSampleUnit::process_package(LoadPackage *package)
127 DownSamplePackage *pkg = (DownSamplePackage*)package;
128 int h = server->output->get_h();
129 int w = server->output->get_w();
132 switch(server->input->get_color_model())
135 DOWNSAMPLE(uint8_t, int64_t, 3, 0xff)
138 DOWNSAMPLE(float, float, 3, 1.0)
141 DOWNSAMPLE(uint8_t, int64_t, 4, 0xff)
144 DOWNSAMPLE(float, float, 4, 1.0)
147 DOWNSAMPLE(uint16_t, int64_t, 3, 0xffff)
149 case BC_RGBA16161616:
150 DOWNSAMPLE(uint16_t, int64_t, 4, 0xffff)
153 DOWNSAMPLE(uint8_t, int64_t, 3, 0xff)
156 DOWNSAMPLE(uint8_t, int64_t, 4, 0xff)
159 DOWNSAMPLE(uint16_t, int64_t, 3, 0xffff)
161 case BC_YUVA16161616:
162 DOWNSAMPLE(uint16_t, int64_t, 4, 0xffff)
172 DownSampleServer::DownSampleServer(int total_clients,
174 : LoadServer(total_clients, total_packages)
178 void DownSampleServer::init_packages()
180 int y1 = vertical_y - vertical;
181 int total_strips = (int)((float)output->get_h() / vertical + 1);
182 int strips_per_package = (int)((float)total_strips / get_total_packages() + 1);
184 for(int i = 0; i < get_total_packages(); i++)
186 DownSamplePackage *package = (DownSamplePackage*)get_package(i);
188 package->y2 = y1 + strips_per_package * vertical;
189 package->y1 = MIN(output->get_h(), package->y1);
190 package->y2 = MIN(output->get_h(), package->y2);
195 LoadClient* DownSampleServer::new_client()
197 return new DownSampleUnit(this);
200 LoadPackage* DownSampleServer::new_package()
202 return new DownSamplePackage;
205 void DownSampleServer::process_frame(VFrame *output,
217 this->output = output;
222 this->vertical = vertical;
223 this->vertical_y = vertical_y;
224 this->horizontal = horizontal;
225 this->horizontal_x = horizontal_x;