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.
20 #include "gstsparrow.h"
26 #define INITIAL_BLACK 32
31 typedef struct sparrow_play_s
{
40 negate(sparrow_play_t
*player
, guint8 in
){
41 return player
->lut
[in
];
44 static void set_up_jpeg(GstSparrow
*sparrow
, sparrow_play_t
*player
){
45 /*XXX pick a jpeg, somehow*/
46 sparrow_frame_t
*frame
= &sparrow
->shared
->index
[player
->jpeg_index
];
47 GST_DEBUG("set up jpeg shared->index is %p, offset %d, frame %p\n",
48 sparrow
->shared
->index
, player
->jpeg_index
, frame
);
49 guint8
*src
= sparrow
->shared
->jpeg_blob
+ frame
->offset
;
51 guint size
= frame
->jpeg_size
;
52 GST_DEBUG("blob is %p, offset %d, src %p, size %d\n",
53 sparrow
->shared
->jpeg_blob
, frame
->offset
, src
, size
);
55 begin_reading_jpeg(sparrow
, src
, size
);
57 if (player
->jpeg_index
== sparrow
->shared
->image_count
){
58 player
->jpeg_index
= 0;
63 static inline guint8
one_subpixel(sparrow_play_t
*player
, guint8 inpix
, guint8 jpegpix
){
64 /* simplest possible */
65 guint sum
= player
->lut
[inpix
] + jpegpix
;
66 //int diff = jpegpix - inpix;
74 do_one_pixel(GstSparrow
*sparrow
, guint8
*outpix
, guint8
*inpix
, guint8
*jpegpix
){
75 /* rather than cancel the whole other one, we need to calculate the
76 difference from the desired image, and only compensate by that
77 amount. If a lot of negative compensation (i.e, trying to blacken)
78 is needed, then it is time to raise the black level for the next
79 round (otherwise, lower the black level). Use sum of
80 compensations?, or count? or thresholded? or squared (via LUT)?
82 How are relative calculations calculated via LUT?
89 sparrow_play_t
*player
= sparrow
->helper_struct
;
90 //guint8 black = player->black_level;
92 int r = ib[sparrow->in.rbyte];
93 int g = ib[sparrow->in.gbyte];
94 int b = ib[sparrow->in.bbyte];
96 //outpix[0] = player->lut[inpix[0]];
97 //outpix[1] = player->lut[inpix[1]];
98 //outpix[2] = player->lut[inpix[2]];
99 //outpix[3] = player->lut[inpix[3]];
100 outpix
[0] = one_subpixel(player
, inpix
[0], jpegpix
[0]);
101 outpix
[1] = one_subpixel(player
, inpix
[1], jpegpix
[1]);
102 outpix
[2] = one_subpixel(player
, inpix
[2], jpegpix
[2]);
103 outpix
[3] = one_subpixel(player
, inpix
[3], jpegpix
[3]);
108 play_from_full_lut(GstSparrow
*sparrow
, guint8
*in
, guint8
*out
){
109 GST_DEBUG("play_from_full_lut\n");
111 memset(out
, 0, sparrow
->out
.size
); /*is this necessary? (only for outside
112 screen map, maybe in-loop might be
115 sparrow_play_t
*player
= sparrow
->helper_struct
;
118 //guint32 *out32 = (guint32 *)out;
119 guint32
*in32
= (guint32
*)in
;
120 set_up_jpeg(sparrow
, player
);
121 GST_DEBUG("in %p out %p", in
, out
);
123 guint8
*jpeg_row
= player
->image_row
;
125 for (oy
= 0; oy
< sparrow
->out
.height
; oy
++){
126 //GST_DEBUG("about to read line to %p", jpeg_row);
127 read_one_line(sparrow
, jpeg_row
);
128 for (ox
= 0; ox
< sparrow
->out
.width
; ox
++, i
++){
129 int x
= sparrow
->map_lut
[i
].x
;
130 int y
= sparrow
->map_lut
[i
].y
;
132 guint8
*inpix
= (guint8
*)&in32
[y
* sparrow
->in
.width
+ x
];
133 do_one_pixel(sparrow
,
136 &jpeg_row
[ox
* PIXSIZE
]);
140 finish_reading_jpeg(sparrow
);
142 if (DEBUG_PLAY
&& sparrow
->debug
){
143 debug_frame(sparrow
, out
, sparrow
->out
.width
, sparrow
->out
.height
, PIXSIZE
);
148 INVISIBLE sparrow_state
149 mode_play(GstSparrow
*sparrow
, guint8
*in
, guint8
*out
){
150 play_from_full_lut(sparrow
, in
, out
);
151 return SPARROW_STATUS_QUO
;
154 static const double GAMMA
= 1.5;
155 static const double INV_GAMMA
= 1.0 / 1.5;
156 static const double FALSE_CEILING
= 275;
159 init_gamma_lut(sparrow_play_t
*player
){
160 for (int i
= 0; i
< 256; i
++){
162 1. perform inverse gamma calculation (-> linear colour space)
168 x
= 1 - pow(x
, INV_GAMMA
);
169 x
= pow(x
, GAMMA
) * FALSE_CEILING
;
173 player
->lut
[i
] = (guint8
)x
;
177 INVISIBLE
void init_play(GstSparrow
*sparrow
){
178 GST_DEBUG("starting play mode\n");
179 init_jpeg_src(sparrow
);
180 sparrow_play_t
*player
= zalloc_aligned_or_die(sizeof(sparrow_play_t
));
181 player
->image_row
= zalloc_aligned_or_die(sparrow
->out
.width
* PIXSIZE
);
182 player
->black_level
= INITIAL_BLACK
;
183 sparrow
->helper_struct
= player
;
184 init_gamma_lut(player
);
185 GST_DEBUG("finished init_play\n");
188 INVISIBLE
void finalise_play(GstSparrow
*sparrow
){
189 GST_DEBUG("leaving play mode\n");