debug messages in play
[sparrow.git] / play.c
blob60d1833d94210bd04c65148aa4762eff96473301
1 /* Copyright (C) <2010> Douglas Bagnall <douglas@halo.gen.nz>
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Library General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
13 * You should have received a copy of the GNU Library General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 02111-1307, USA.
19 #include "sparrow.h"
20 #include "gstsparrow.h"
22 #include <string.h>
23 #include <math.h>
25 #define DEBUG_PLAY 0
26 #define INITIAL_BLACK 32
27 #define MIN_BLACK 0
28 #define MAX_BLACK 160
31 typedef struct sparrow_play_s{
32 guint8 lut[256];
33 guint8 *image_row;
34 guint8 black_level;
35 guint jpeg_index;
36 } sparrow_play_t;
39 static inline guint8
40 negate(sparrow_play_t *player, guint8 in){
41 return player->lut[in];
44 static void UNUSED
45 play_from_lut(GstSparrow *sparrow, guint8 *in, guint8 *out){
46 sparrow_map_t *map = &sparrow->map;
47 memset(out, 0, sparrow->out.size);
48 int x, y;
49 guint32 *line = (guint32 *)out;
50 for (y = 0; y < sparrow->out.height; y++){
51 sparrow_map_row_t *row = map->rows + y;
52 for(x = row->start; x < row->end; x++){
53 line[x] = ~0;
56 GST_DEBUG("row %p %d: s %d e%d line %d\n",
57 row, y, row->start, row->end, line);
59 line += sparrow->out.width;
63 static void set_up_jpeg(GstSparrow *sparrow, sparrow_play_t *player){
64 /*XXX pick a jpeg, somehow*/
65 sparrow_frame_t *frame = &sparrow->shared->index[player->jpeg_index];
66 GST_DEBUG("set up jpeg shared->index is %p, offset %d, frame %p\n",
67 sparrow->shared->index, player->jpeg_index, frame);
68 guint8 *src = sparrow->shared->jpeg_blob + frame->offset;
70 guint size = frame->jpeg_size;
71 GST_DEBUG("blob is %p, offset %d, src %p, size %d\n",
72 sparrow->shared->jpeg_blob, frame->offset, src, size);
74 begin_reading_jpeg(sparrow, src, size);
75 player->jpeg_index++;
76 if (player->jpeg_index == sparrow->shared->image_count){
77 player->jpeg_index = 0;
82 static inline guint8 one_subpixel(sparrow_play_t *player, guint8 inpix, guint8 jpegpix){
83 /* simplest possible */
84 guint sum = player->lut[inpix] + jpegpix;
85 //int diff = jpegpix - inpix;
88 return sum >> 1;
89 //return jpegpix;
92 static inline void
93 do_one_pixel(GstSparrow *sparrow, guint8 *outpix, guint8 *inpix, guint8 *jpegpix){
94 /* rather than cancel the whole other one, we need to calculate the
95 difference from the desired image, and only compensate by that
96 amount. If a lot of negative compensation (i.e, trying to blacken)
97 is needed, then it is time to raise the black level for the next
98 round (otherwise, lower the black level). Use sum of
99 compensations?, or count? or thresholded? or squared (via LUT)?
101 How are relative calculations calculated via LUT?
103 1. pre scale
104 2. combine
105 3. re scale
108 sparrow_play_t *player = sparrow->helper_struct;
109 //guint8 black = player->black_level;
111 int r = ib[sparrow->in.rbyte];
112 int g = ib[sparrow->in.gbyte];
113 int b = ib[sparrow->in.bbyte];
115 //outpix[0] = player->lut[inpix[0]];
116 //outpix[1] = player->lut[inpix[1]];
117 //outpix[2] = player->lut[inpix[2]];
118 //outpix[3] = player->lut[inpix[3]];
119 outpix[0] = one_subpixel(player, inpix[0], jpegpix[0]);
120 outpix[1] = one_subpixel(player, inpix[1], jpegpix[1]);
121 outpix[2] = one_subpixel(player, inpix[2], jpegpix[2]);
122 outpix[3] = one_subpixel(player, inpix[3], jpegpix[3]);
125 static inline guint8* get_in_pixel(GstSparrow *sparrow, guint32 *in32, int x, int y){
126 /* one day, might average from indicated pixels */
127 x >>= SPARROW_MAP_LUT_SHIFT;
128 y >>= SPARROW_MAP_LUT_SHIFT;
129 return (guint8 *)&in32[y * sparrow->in.width + x];
132 static void
133 play_from_full_lut(GstSparrow *sparrow, guint8 *in, guint8 *out){
134 GST_DEBUG("play_from_full_lut\n");
135 memset(out, 0, sparrow->out.size); /*is this necessary? (only for outside
136 screen map, maybe in-loop might be
137 quicker) */
138 sparrow_play_t *player = sparrow->helper_struct;
139 guint i;
140 int ox, oy;
141 //guint32 *out32 = (guint32 *)out;
142 guint32 *in32 = (guint32 *)in;
143 set_up_jpeg(sparrow, player);
144 GST_DEBUG("in %p out %p", in, out);
146 guint8 *jpeg_row = player->image_row;
147 i = 0;
148 for (oy = 0; oy < sparrow->out.height; oy++){
149 //GST_DEBUG("about to read line to %p", player->image_row);
150 read_one_line(sparrow, player->image_row);
151 for (ox = 0; ox < sparrow->out.width; ox++, i++){
152 int x = sparrow->map_lut[i].x;
153 int y = sparrow->map_lut[i].y;
154 if (x || y){
155 //GST_DEBUG("in %p x %d y %d", in, x, y);
156 guint8 *inpix = get_in_pixel(sparrow, in32, x, y);
157 do_one_pixel(sparrow,
158 &out[i * PIXSIZE],
159 inpix,
160 &jpeg_row[ox * PIXSIZE]);
164 finish_reading_jpeg(sparrow);
166 if (DEBUG_PLAY && sparrow->debug){
167 debug_frame(sparrow, out, sparrow->out.width, sparrow->out.height, PIXSIZE);
173 INVISIBLE sparrow_state
174 mode_play(GstSparrow *sparrow, guint8 *in, guint8 *out){
175 //do actual stuff here
176 //memcpy(out, in, sparrow->out.size);
177 //simple_negation(out, sparrow->out.size);
178 #if USE_FULL_LUT
179 play_from_full_lut(sparrow, in, out);
180 #else
181 play_from_lut(sparrow, in, out);
182 #endif
183 return SPARROW_STATUS_QUO;
186 static const double GAMMA = 1.5;
187 static const double INV_GAMMA = 1.0 / 1.5;
188 static const double FALSE_CEILING = 275;
190 static void
191 init_gamma_lut(sparrow_play_t *player){
192 for (int i = 0; i < 256; i++){
193 /* for each colour:
194 1. perform inverse gamma calculation (-> linear colour space)
195 2. negate
196 3 undo gamma.
198 double x;
199 x = i / 255.01;
200 x = 1 - pow(x, INV_GAMMA);
201 x = pow(x, GAMMA) * FALSE_CEILING;
202 if (x > 255){
203 x = 255;
205 player->lut[i] = (guint8)x;
210 INVISIBLE void init_play(GstSparrow *sparrow){
211 GST_DEBUG("starting play mode\n");
212 init_jpeg_src(sparrow);
213 sparrow_play_t *player = zalloc_aligned_or_die(sizeof(sparrow_play_t));
214 player->image_row = zalloc_aligned_or_die(sparrow->out.width * PIXSIZE);
215 player->black_level = INITIAL_BLACK;
216 sparrow->helper_struct = player;
217 init_gamma_lut(player);
219 GST_DEBUG("finished init_play\n");
222 INVISIBLE void finalise_play(GstSparrow *sparrow){
223 GST_DEBUG("leaving play mode\n");