scanline.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008,2001,2000,1999 Sasha Vasko <sasha at aftercode.net>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 #ifdef _WIN32
00020 #include "win32/config.h"
00021 #else
00022 #include "config.h"
00023 #endif
00024 
00025 #define LOCAL_DEBUG
00026 #include <string.h>
00027 #ifdef HAVE_UNISTD_H
00028 #include <unistd.h>
00029 #endif
00030 #ifdef HAVE_STDLIB_H
00031 #include <stdlib.h>
00032 #endif
00033 #ifdef HAVE_STDARG_H
00034 #include <stdarg.h>
00035 #endif
00036  
00037 #ifdef _WIN32
00038 # include "win32/afterbase.h"
00039 #else
00040 # include "afterbase.h"
00041 #endif
00042 #include "scanline.h"
00043 
00044 
00045 /* ********************* ASScanline ************************************/
00046 ASScanline*
00047 prepare_scanline( unsigned int width, unsigned int shift, ASScanline *reusable_memory, Bool BGR_mode  )
00048 {
00049         register ASScanline *sl = reusable_memory ;
00050         size_t aligned_width;
00051         void *ptr;
00052 
00053         if( sl == NULL )
00054                 sl = safecalloc( 1, sizeof( ASScanline ) );
00055         else
00056                 memset( sl, 0x00, sizeof(ASScanline));
00057 
00058         if( width == 0 ) width = 1 ;
00059         sl->width       = width ;
00060         sl->shift   = shift ;
00061         /* we want to align data by 8 byte boundary (double)
00062          * to allow for code with less ifs and easier MMX/3Dnow utilization :*/
00063         aligned_width = width + (width&0x00000001);
00064         sl->buffer = ptr = safecalloc (1, ((aligned_width*4)+16)*sizeof(CARD32)+8);
00065         if (ptr == NULL)
00066         {
00067                 if (sl != reusable_memory)
00068                         free (sl);
00069                 return NULL;
00070         }
00071 
00072         sl->xc1 = sl->red       = (CARD32*)((((long)ptr+7)>>3)*8);
00073         sl->xc2 = sl->green = sl->red   + aligned_width;
00074         sl->xc3 = sl->blue      = sl->green + aligned_width;
00075         sl->alpha       = sl->blue  + aligned_width;
00076 
00077         sl->channels[IC_RED] = sl->red ;
00078         sl->channels[IC_GREEN] = sl->green ;
00079         sl->channels[IC_BLUE] = sl->blue ;
00080         sl->channels[IC_ALPHA] = sl->alpha ;
00081 
00082         if( BGR_mode )
00083         {
00084                 sl->xc1 = sl->blue ;
00085                 sl->xc3 = sl->red ;
00086         }
00087         /* this way we can be sure that our buffers have size of multiplies of 8s
00088          * and thus we can skip unneeded checks in code */
00089 #if 0
00090         /* initializing padding into 0 to avoid any garbadge carry-over
00091          * bugs with diffusion: */
00092         sl->red[aligned_width-1]   = 0;
00093         sl->green[aligned_width-1] = 0;
00094         sl->blue[aligned_width-1]  = 0;
00095         sl->alpha[aligned_width-1] = 0;
00096 #endif  
00097         sl->back_color = ARGB32_DEFAULT_BACK_COLOR;
00098 
00099         return sl;
00100 }
00101 
00102 void
00103 free_scanline( ASScanline *sl, Bool reusable )
00104 {
00105         if( sl )
00106         {
00107                 if( sl->buffer )
00108                         free( sl->buffer );
00109                 if( !reusable )
00110                         free( sl );
00111         }
00112 }
00113 
00114 /* demosaicing */
00115 void
00116 destroy_asim_strip (ASIMStrip **pstrip)
00117 {
00118         if (pstrip)
00119         {
00120                 ASIMStrip *strip = *pstrip;
00121                 if (strip)
00122                 {
00123                         int i;
00124                         if (strip->lines)
00125                         {
00126                                 for (i = 0; i < strip->size; ++i)
00127                                         free_scanline (strip->lines[i], False);
00128                                 free (strip->lines);
00129                         }
00130                         if (strip->aux_data)
00131                         {
00132                                 for (i = 0; i < strip->size; ++i )
00133                                         if (strip->aux_data[i])
00134                                                 free(strip->aux_data[i]);
00135                                 free (strip->aux_data); 
00136                         }
00137                         free (strip);
00138                         *pstrip = NULL;
00139                 }
00140         }
00141 }
00142 
00143 ASIMStrip *
00144 create_asim_strip(unsigned int size, unsigned int width, int shift, int bgr)
00145 {
00146         ASIMStrip *strip;
00147         int i;
00148         
00149         if (width == 0 || size == 0)
00150                 return NULL;
00151         
00152         strip = safecalloc( 1, sizeof(ASIMStrip));
00153         strip->size = size;
00154         
00155         if ((strip->lines = safecalloc (size, sizeof(ASScanline*))) == NULL)
00156         {
00157                 free (strip);
00158                 return NULL;
00159         }
00160 
00161         if ((strip->aux_data = safecalloc (size, sizeof(void*))) == NULL)
00162         {
00163                 destroy_asim_strip (&strip);
00164                 return NULL;
00165         }
00166         
00167         for (i = 0 ; i < (int)size; ++i)
00168                 if ((strip->lines[i] = prepare_scanline (width, shift, NULL, bgr)) == NULL)
00169                 {
00170                         strip->size = i;
00171                         destroy_asim_strip (&strip);
00172                         return NULL;
00173                 }
00174 
00175         strip->width = width;
00176         strip->start_line = 0;
00177         
00178         return strip;
00179 }
00180 
00181 void
00182 advance_asim_strip (ASIMStrip *strip)
00183 {
00184         ASScanline *tmp = strip->lines[0];
00185         void *aux_tmp = strip->aux_data[0];
00186         int i;
00187         
00188         /* move all scanlines up, shuffling first scanline to the back */
00189         for (i = 0 ; i < strip->size-1; ++i )
00190         {
00191                 strip->lines[i] = strip->lines[i+1];
00192                 strip->aux_data[i] = strip->aux_data[i+1];
00193         }
00194         strip->lines[strip->size-1] = tmp;
00195         strip->aux_data[strip->size-1] = aux_tmp;
00196 
00197         /* clear the state of the scanline : */
00198         tmp->flags = 0; 
00199 
00200         strip->start_line++;
00201 } 
00202 
00203 /* returns number of lines processed from the data */
00204 int
00205 load_asim_strip (ASIMStrip *strip, CARD8 *data, int data_size, int data_start_line, int data_row_size, 
00206                                  ASIMStripLoader *line_loaders, int line_loaders_num)
00207 {
00208         int line = 0;
00209         int loaded = 0;
00210         
00211         if (strip == NULL || data == NULL || data_size <= 0 || data_row_size <= 0 || line_loaders == NULL)
00212                 return 0;
00213         line = data_start_line - strip->start_line;
00214         if (line < 0)
00215         {
00216                 data += data_row_size*(-line);
00217                 data_size -= data_row_size*(-line);
00218                 line = 0;
00219         }
00220                 
00221         while (line < strip->size && data_size > 0)
00222         {
00223                 int loader = (strip->start_line+line)%line_loaders_num;
00224                 if (!ASIM_IsStripLineLoaded(strip,line) && line_loaders[loader])
00225                         line_loaders[loader] (strip->lines[line], data, data_size);
00226 
00227                 ++line;
00228                 ++loaded;
00229                 data_size -= data_row_size;
00230                 data += data_row_size;
00231         }
00232         return loaded;
00233 }
00234 
00235 static int
00236 decode_12_be (CARD32 *c1, CARD32 *c2, CARD8 *data, int width, int data_size)
00237 {
00238         int x;
00239         int max_x = (data_size*2)/3;
00240         
00241         if (max_x > width)
00242                 max_x = width;
00243         
00244         if (max_x > 0)
00245         {
00246 #if defined(LOCAL_DEBUG) && !defined(NO_DEBUG_OUTPUT)
00247                 fprintf (stderr, "decode_12_be CFA data : ");           
00248                 for (x = 0 ; x < (max_x*3)/2; x += 3)
00249                         fprintf (stderr, " |%2.2X %2.2X %2.2X", data[x], data[x+1], data[x+2]);                         
00250                 fprintf (stderr, "\n");         
00251 #endif
00252                 for (x = 0 ; x+1 < max_x; ++x)
00253                 {
00254                         CARD32 tail = ((CARD32)data[1])&0x00F0;
00255                         c1[x] = (((CARD32)data[0]) << 8)|tail|(tail>>4);
00256                         c2[x] = ASIM_SCL_MissingValue;
00257                         
00258                         ++x;
00259                         tail = data[2]&0x0F;
00260                         c1[x] = ASIM_SCL_MissingValue;
00261                         c2[x] = (((CARD32)data[1]&0x0f) << 12)| ((CARD32)data[2]<<4) |tail;
00262                         
00263                         data += 3;
00264                 }
00265 
00266                 if (x < max_x)
00267                 {
00268                         CARD32 tail = ((CARD32)data[1])&0x00F0;
00269                         c1[x] = (((CARD32)data[0]) << 8)|tail|(tail>>4);
00270                         c2[x] = ASIM_SCL_MissingValue;
00271                 }
00272 
00273 #if 0
00274 #if defined(LOCAL_DEBUG) && !defined(NO_DEBUG_OUTPUT)   
00275 fprintf (stderr, "decode_12_be  C1 data : ");           
00276         for (x = 0 ; x < max_x; ++x)
00277                 fprintf (stderr, " %4.4X", c1[x]);                                              
00278 fprintf (stderr, "\ndecode_12_be  C2 data : ");         
00279         for (x = 0 ; x < max_x; ++x)
00280                 fprintf (stderr, " %4.4X", c2[x]);                                              
00281 fprintf (stderr, "\n");                         
00282 #endif
00283 #endif
00284         }
00285         return max_x;
00286 } 
00287 
00288 void decode_BG_12_be (ASScanline *scl, CARD8 *data, int data_size)
00289 {
00290         if (decode_12_be (scl->blue, scl->green, data, scl->width, data_size))
00291                 set_flags (scl->flags, SCL_DO_GREEN|SCL_DO_BLUE);
00292 }
00293 
00294 void decode_GR_12_be (ASScanline *scl, CARD8 *data, int data_size)
00295 {
00296         if (decode_12_be (scl->green, scl->red, data, scl->width, data_size))   
00297                 set_flags (scl->flags, SCL_DO_GREEN|SCL_DO_RED);
00298 }
00299 
00300 void decode_RG_12_be (ASScanline *scl, CARD8 *data, int data_size)
00301 {
00302         if (decode_12_be (scl->red, scl->green, data, scl->width, data_size))
00303                 set_flags (scl->flags, SCL_DO_GREEN|SCL_DO_RED);
00304 }
00305 
00306 void decode_GB_12_be (ASScanline *scl, CARD8 *data, int data_size)
00307 {
00308         if (decode_12_be (scl->green, scl->blue, data, scl->width, data_size))
00309                 set_flags (scl->flags, SCL_DO_GREEN|SCL_DO_BLUE);
00310 }
00311 
00312 /* min gradient interpolation : */
00313 typedef void (*ASIMDiagInterpolationFunc) (CARD32 *dst, CARD32 **channs, int width, int offset);
00314 
00315 #define ASIM_ChooseInterpolationGradient(g1,g2)  ((g1/16)*(g1/16)>(g2/16)*(g2/16)?(g1):(g2))
00316 
00317 void
00318 interpolate_channel_v_15x51 (CARD32 *dst, CARD32 **channs, int width, int offset)
00319 {
00320         /* Assumptions :  channs is array of 5 CARD32 pointers not NULL */
00321         int x;
00322         for (x = 0; x < width; ++x)
00323         {
00324                 int v = (int)channs[1][x]*5+(int)channs[3][x]*5-(int)channs[4][x]-(int)channs[0][x];
00325                 dst[x] = v <= 0 ? 0 : v >>3;
00326         }
00327 }
00328 
00329 void
00330 interpolate_channel_v_checkered_15x51 (CARD32 *dst, CARD32 **channs, int width, int offset)
00331 {
00332         /* Assumptions :  channs is array of 5 CARD32 pointers not NULL */
00333         int x = offset;
00334         for (x = 0; x < width; ++x, ++x)
00335         {
00336                 int v = (int)channs[1][x]*5+(int)channs[3][x]*5-(int)channs[4][x]-(int)channs[0][x];
00337                 dst[x] = v <= 0 ? 0 : v >>3;
00338         }
00339 }
00340 
00341 /* vert smoothing */
00342 void
00343 smooth_channel_v_15x51 (CARD32 *dst, CARD32 **channs, int width, int offset)
00344 {
00345         /* Assumptions :  channs is array of 5 CARD32 pointers not NULL */
00346         int x;
00347         for (x = 0; x < width; ++x)
00348         {
00349                 int v = (int)(channs[2][x]<<3) + (int)channs[1][x]*5+(int)channs[3][x]*5-(int)channs[4][x]-(int)channs[0][x];
00350                 dst[x] = v <= 0 ? 0 : v >>4;
00351         }
00352 }
00353 
00354 /* horizontal interpolation */
00355 void
00356 interpolate_channel_h_105x501 (CARD32 *chan, int width)
00357 {
00358         int v;
00359         int chan0 = chan[0];
00360         int x = 1;
00361         
00362         /* interpolating every other pixel from its 5 neighbours */
00363         /* Assumptions :  width > 4 and width%2 == 0 */
00364         if (ASIM_IsMissingValue(chan0))
00365         {
00366                 x = 0;
00367                 chan0 = chan[1];
00368         }
00369         
00370         v = (int)chan0*4 + (int)chan[x+1]*5 - (int)chan[x+3];
00371 
00372         chan[x] = v < 0 ? 0: v>>3 ;
00373 
00374         v -= (int)chan0*5;
00375 
00376         if (x == 0)
00377         {
00378                 x += 2; 
00379                 v += (int)chan[x+1]*6 - (int)chan[x+3];
00380                 chan[x] = v < 0 ? 0: v>>3 ;
00381                 v -= (int)chan[x-1]*6 - (int)chan0;
00382         }
00383 
00384         for ( x += 2 ; x+3 < width; x += 2)
00385         {
00386                 v += (int)chan[x+1]*6 - (int)chan[x+3];
00387                 chan[x] = v < 0 ? 0: v>>3 ;
00388                 v -= (int)chan[x-1]*6 - (int)chan[x-3];
00389         }
00390 
00391         v = (int)chan[x+1]+(int)chan[x-1]*4-(int)chan[x-3];
00392         chan[x] = v <= 0 ? 0 : v >>2;
00393         v = (int)chan[x+2-1]*3 - (int)chan[x+2-3];
00394         chan[x+2] = v <= 0 ? 0 : v >> 1 ;
00395 }
00396 
00397 void
00398 interpolate_channel_h_grad3 (CARD32 *c1, CARD32 *c2, int width)
00399 {/* interpolate missing values in c2, minimizing variation of different from c2 */
00400         int v;
00401         int chan0 = c1[0];
00402         int x = 1;
00403 
00404         if (ASIM_IsMissingValue(chan0))
00405         {
00406                 x = 0;  
00407         }
00408 
00409         v = (int)c2[x] + (int)c1[x+1] - (int)c2[x+2];
00410         c1[x] = v <= 0 ? 0 : v;
00411         
00412         for( x += 2; x+2 < width ; x += 2)
00413         {
00414                 v = (int)(c2[x]<<1) + (int)c1[x-1] + (int)c1[x+1] - (int)c2[x+2] - (int)c2[x-2];
00415                 c1[x] = v <= 0 ? 0 : v>>1;
00416         }
00417         
00418         if (x < width)
00419         {
00420                 v = (int)c2[x] + (int)c1[x-1] - (int)c2[x-2];
00421                 c1[x] = v <= 0 ? 0 : v;
00422         }
00423 }
00424 
00425 void print_16bit_chan (CARD32 *chan, int width)
00426 {
00427         int x;
00428         for (x = 0 ; x < width ; ++x ) 
00429         { 
00430                 int v = chan[x]; 
00431                 fprintf(stderr, " %5.5d", (v < 0)?99999:v );
00432         }
00433         fprintf( stderr, "\n");
00434 }
00435 
00436 Bool
00437 interpolate_asim_strip_gradients (ASIMStrip *strip, int line, int chan_from, int chan_to, int offset, ASIMDiagInterpolationFunc func )
00438 {
00439         CARD32 *chan_lines[5] = {NULL, NULL, NULL, NULL, NULL};
00440         int above = 2, below = 2;
00441         int i = line;
00442         int chan = chan_to;
00443 
00444         while (--i >= 0 && below > 0)
00445                 if (get_flags(strip->lines[i]->flags, 0x01<<chan))
00446                 {
00447                         chan_lines[--below] = strip->lines[i]->channels[chan];
00448                         chan = (chan == chan_to) ? chan_from : chan_to;
00449                 }
00450         if (below > 0)
00451                 return False;
00452 
00453         chan_lines[2] = strip->lines[line]->channels[chan_from];
00454         /* chan here should be in proper position if below == 0 */
00455 
00456         i = line ;
00457         while (++i < strip->size && above < 4)
00458         {
00459                 if (get_flags(strip->lines[i]->flags, 0x01<<chan))
00460                 {
00461                         chan_lines[++above] = strip->lines[i]->channels[chan];
00462                         chan = (chan == chan_to) ? chan_from : chan_to;
00463                 }
00464         }
00465 
00466         if (above < 4) /* not enough data for interpolation */
00467                 return False;
00468 
00469 #if 0
00470 print_16bit_chan (chan_lines[0], strip->lines[line]->width); 
00471 print_16bit_chan (chan_lines[1], strip->lines[line]->width); 
00472 print_16bit_chan (chan_lines[2], strip->lines[line]->width); 
00473 print_16bit_chan (chan_lines[3], strip->lines[line]->width); 
00474 print_16bit_chan (chan_lines[4], strip->lines[line]->width); 
00475 #endif
00476 
00477 fprintf( stderr, "Line %d, start_line = %d, offset = %d, chan_to = %d, chan_from = %d\n", line, strip->start_line, offset, chan_to, chan_from);
00478         func (strip->lines[line]->channels[chan_to], chan_lines, strip->lines[line]->width, offset);
00479 
00480 #if 0
00481 print_16bit_chan (strip->lines[line]->channels[chan_to], strip->lines[line]->width); 
00482 fprintf( stderr, "\n");
00483 #endif
00484         
00485         return True;
00486 }
00487 
00488 static inline int*
00489 checkalloc_diff_aux_data (ASIMStrip *strip, int line) 
00490 {
00491         if (strip->aux_data[line] == NULL)
00492                 strip->aux_data[line] = safemalloc(strip->lines[line]->width*2*sizeof(int));
00493         return strip->aux_data[line];
00494 }
00495 
00496 void
00497 interpolate_channel_hv_adaptive_1x1(CARD32 *above, CARD32 *dst, CARD32 *below, int width, int offset)
00498 {
00499         int x = offset;
00500         
00501         if (offset == 0)
00502         {
00503                 dst[0] = (above[0] + below[0] + dst[1])/3;
00504                 x += 2;
00505         }
00506         
00507         for (; x < width-1; ++x, ++x)
00508         {
00509                 int v;
00510                 int l = dst[x-1], r = dst[x+1];
00511                 /* we have to operate with 14 bit values in order to avoid overflow */
00512                 int diff_h = (l>>2)-(r>>2);
00513                 int t = above[x], b = below[x];
00514                 int diff_v = (t>>2)-(b>>2);
00515                 if ((diff_h * diff_h) < (diff_v * diff_v))
00516                 {
00517                         v = (l + r) >> 1;
00518                         if ((v < t && v < b) || (v > t && v > b))
00519                                 v  = ((v << 1) + b + t) >> 2 ;
00520                 }else
00521                 {
00522                         v = (t + b) >> 1;
00523                         if ((v < l && v < r) || (v > l && v > r))
00524                                 v  = ((v << 1) + l + r) >> 2 ;
00525                 }
00526                 dst[x] = v;
00527                 
00528         }
00529         if (offset == 1)
00530                 dst[x] = (above[x] + below[x] + dst[x-1])/3;
00531 }
00532 
00533 Bool calculate_green_diff(ASIMStrip *strip, int line, int chan, int offset)
00534 {
00535         int width = strip->lines[line]->width;
00536         CARD32 *green = strip->lines[line]->green;
00537         CARD32 *src = strip->lines[line]->channels[chan];
00538         int *diff = checkalloc_diff_aux_data (strip, line);
00539         int x = offset;
00540         int v_last, v;
00541         
00542         if (diff == NULL)
00543                 return False;
00544 
00545         if (chan == ARGB32_BLUE_CHAN)
00546                 diff += width;
00547 
00548         v_last = (int)src[x] - (int)green[x];
00549         diff[x] = v_last;
00550         /* some loop unrolling for optimization purposes - 
00551            we don't want to store diff[x] untill the second pass */
00552         x +=2;
00553         v = (int)src[x] - (int)green[x];
00554         diff[x-1] = (v + v_last)/2;
00555         diff[x] = v_last = v;
00556         
00557         while ((x += 2) < width-2)
00558         {
00559                 v = (int)src[x] - (int)green[x];
00560 
00561                 diff[x-1] = (v + v_last)/2;
00562                 v_last = v;
00563         }
00564 
00565         v = (int)src[x] - (int)green[x];
00566         diff[x-1] = (v + v_last)/2;
00567         diff[x] = v;
00568         
00569         /* border condition handling : */
00570         if (offset)
00571                 diff[0] = diff[1];
00572         else
00573                 diff[width-1] = diff[width-2];
00574 
00575         /* second pass - further smoothing of the difference at the points 
00576            where we are most likely to see artifacts */
00577         for (x = offset + 2; x < width-2 ; ++x,++x)
00578                 diff[x] = (diff[x-1]+diff[x+1])/2;
00579         
00580         return True;    
00581 }
00582 
00583 Bool 
00584 interpolate_green_diff(ASIMStrip *strip, int line, int chan, int offset)
00585 {
00586         if (line > 0 && line < strip->size-1)
00587         {
00588                 ASScanline *above = strip->lines[line-1];
00589                 ASScanline *below = strip->lines[line+1];
00590                 ASFlagType flag = (chan == ARGB32_RED_CHAN)?ASIM_SCL_RGDiffCalculated:ASIM_SCL_BGDiffCalculated;
00591                 if (get_flags (above->flags, flag) && get_flags (below->flags, flag))
00592                 {
00593                         int *diff_above = strip->aux_data[line-1];
00594                         int *diff_below = strip->aux_data[line+1];
00595                         int *diff = checkalloc_diff_aux_data (strip, line);
00596                         int max_x = above->width;
00597                         int x = 0;
00598 
00599                         if (diff == NULL)
00600                                 return False;
00601 
00602                         if (chan == ARGB32_BLUE_CHAN)
00603                         {
00604                                 x = max_x;
00605                                 max_x *= 2;
00606                         }
00607                         for (; x < max_x; ++x)
00608                                 diff[x] = (diff_above[x] + diff_below[x])/2;
00609                         return True;
00610                 }
00611         }
00612         return False;
00613 }
00614 
00615 Bool 
00616 interpolate_from_green_diff(ASIMStrip *strip, int line, int chan, int offset)
00617 {
00618         int width = strip->lines[line]->width;
00619         CARD32 *green = strip->lines[line]->green;
00620         CARD32 *dst = strip->lines[line]->channels[chan];
00621         int *diff = strip->aux_data[line];
00622         int x;
00623         
00624         if (diff == NULL)
00625                 return False;
00626 
00627         if (chan == ARGB32_BLUE_CHAN)
00628                 diff += width;
00629         
00630         for (x = 0 ; x < width; ++x)
00631         {
00632                 int v = (int)green[x];
00633                 v += diff[x];
00634                 dst[x] = (v<0)? 0 : v;
00635         }
00636 
00637         return True;    
00638 }
00639 
00640 
00641 void
00642 interpolate_asim_strip_custom_rggb2 (ASIMStrip *strip, ASFlagType filter, Bool force_all)
00643 {
00644         int line;
00645 #if 0
00646         int chan;
00647         for (line = 0; line < 2 ; ++line)
00648                 for (chan = 0 ; chan < IC_NUM_CHANNELS ; ++chan)
00649                         if ( get_flags( filter, 0x01<<chan) )
00650                         {
00651                                 if (!get_flags(strip->lines[line]->flags, 0x01<<chan))
00652                                 {
00653                                         copy_component (strip->lines[line+1]->channels[chan], strip->lines[line]->channels[chan], 0, strip->lines[line]->width);
00654                                         set_flags (strip->lines[0]->flags, 0x01<<chan);
00655                                 }
00656 #if 1
00657                                 if (!get_flags(strip->lines[line]->flags, (ASIM_SCL_InterpolatedV|ASIM_SCL_InterpolatedH)<<chan))
00658                                 {
00659                                         interpolate_channel_h_105x501 (strip->lines[line]->channels[chan], strip->lines[line]->width);
00660                                         set_flags(strip->lines[line]->flags, ASIM_SCL_InterpolatedH<<chan);
00661                                 }
00662 #endif                          
00663                         }
00664 
00665         if (force_all)
00666                 for (line = strip->size-2; strip->size ; ++line)
00667                         for (chan = 0 ; chan < IC_NUM_CHANNELS ; ++chan)
00668                                 if ( get_flags( filter, 0x01<<chan) )
00669                                 {
00670                                         if (!get_flags(strip->lines[line]->flags, 0x01<<chan))
00671                                         {
00672                                                 copy_component (strip->lines[line-1]->channels[chan], strip->lines[line]->channels[chan], 0, strip->lines[line]->width);
00673                                                 set_flags (strip->lines[0]->flags, 0x01<<chan);
00674                                         }
00675 
00676                                         if (!get_flags(strip->lines[line]->flags, (ASIM_SCL_InterpolatedV|ASIM_SCL_InterpolatedH)<<chan))
00677                                         {
00678                                                 interpolate_channel_h_105x501 (strip->lines[line]->channels[chan], strip->lines[line]->width);
00679                                                 set_flags(strip->lines[line]->flags, ASIM_SCL_InterpolatedH<<chan);
00680                                         }
00681                                 }
00682 
00683 #endif
00684 
00685 #if 1
00686         /* interpolation of green */
00687         if ( get_flags( filter, SCL_DO_GREEN) )
00688         {
00689                 for (line = 1 ; line < strip->size-1 ; ++line)
00690                         if (get_flags(strip->lines[line]->flags, SCL_DO_GREEN)
00691                                 && !get_flags(strip->lines[line]->flags, (ASIM_SCL_InterpolatedV<<ARGB32_GREEN_CHAN)))
00692                         {
00693                                 if (get_flags(strip->lines[line-1]->flags, SCL_DO_GREEN)
00694                                         && get_flags(strip->lines[line+1]->flags, SCL_DO_GREEN))
00695                                 {
00696                                         interpolate_channel_hv_adaptive_1x1 (strip->lines[line-1]->green, 
00697                                                                                                                  strip->lines[line]->green, 
00698                                                                                                                  strip->lines[line+1]->green,
00699                                                                                                                  strip->lines[line]->width,
00700                                                                                                                  ASIM_IsMissingValue(strip->lines[line]->green[0])?0:1);
00701                                         set_flags(strip->lines[line]->flags, (ASIM_SCL_InterpolatedH|ASIM_SCL_InterpolatedV)<<ARGB32_GREEN_CHAN);
00702 //                                      strip->lines[line]->flags =  SCL_DO_GREEN| ((ASIM_SCL_InterpolatedH|ASIM_SCL_InterpolatedV)<<ARGB32_GREEN_CHAN);
00703                                 }
00704                         }
00705         }
00706 #endif
00707 
00708 /* now that we have smooth subtrate of green - we can build red/blue channels : 
00709  *   1) Calculate R-G difference for all RG lines, averaging missing values from 2 neightbours
00710  *   2) Calculate R-G difference for all GB lines, averaging values from lines above and below it.
00711  *   3) Calculate ALL RED values by adding calulated difference to Green channel.
00712  *  Do the same for BLUE.
00713  */
00714 #if 1
00715         /* interpolation of red from green + (R-G) */
00716         if ( get_flags( filter, SCL_DO_RED) )
00717         {
00718                 /* step 1. Calculating R-G for RG lines */
00719                 for (line = 0 ; line < strip->size ; ++line)
00720                         if (get_flags(strip->lines[line]->flags, SCL_DO_RED)
00721                                 && !get_flags(strip->lines[line]->flags, ASIM_SCL_RGDiffCalculated)
00722                             && get_flags(strip->lines[line]->flags, SCL_DO_GREEN)
00723                                 && get_flags(strip->lines[line]->flags, (ASIM_SCL_InterpolatedAll<<ARGB32_GREEN_CHAN)))
00724                         {
00725                                 if (calculate_green_diff(strip, line, ARGB32_RED_CHAN, 0))
00726                                         set_flags(strip->lines[line]->flags, ASIM_SCL_RGDiffCalculated);
00727                         }
00728                 /* step 2. Calculating R-G for GB lines */
00729                 for (line = 0 ; line < strip->size ; ++line)
00730                         if (!get_flags(strip->lines[line]->flags, SCL_DO_RED)
00731                                 && !get_flags(strip->lines[line]->flags, ASIM_SCL_RGDiffCalculated))
00732                         {
00733                                 if (interpolate_green_diff(strip, line, ARGB32_RED_CHAN, 0))
00734                                         set_flags(strip->lines[line]->flags, ASIM_SCL_RGDiffCalculated);
00735                         }
00736                 /* step 3. Calculating RED from green + R-G */
00737                 for (line = 0 ; line < strip->size ; ++line)
00738                         if (get_flags(strip->lines[line]->flags, ASIM_SCL_RGDiffCalculated)
00739                             && !get_flags(strip->lines[line]->flags, (ASIM_SCL_InterpolatedAll<<ARGB32_RED_CHAN)))
00740                         {
00741                                 if (interpolate_from_green_diff(strip, line, ARGB32_RED_CHAN, 0))
00742                                         set_flags(strip->lines[line]->flags, SCL_DO_RED|(ASIM_SCL_InterpolatedAll<<ARGB32_RED_CHAN));
00743                         }
00744         }
00745 #endif
00746 #if 1
00747         /* interpolation of blue from green + (B-G) */
00748         if ( get_flags( filter, SCL_DO_BLUE) )
00749         {
00750                 /* step 1. Calculating B-G for GB lines */
00751                 for (line = 0 ; line < strip->size ; ++line)
00752                         if (get_flags(strip->lines[line]->flags, SCL_DO_BLUE)
00753                                 && !get_flags(strip->lines[line]->flags, ASIM_SCL_BGDiffCalculated)
00754                             && get_flags(strip->lines[line]->flags, SCL_DO_GREEN)
00755                                 && get_flags(strip->lines[line]->flags, (ASIM_SCL_InterpolatedAll<<ARGB32_GREEN_CHAN)))
00756                         {
00757                                 if (calculate_green_diff(strip, line, ARGB32_BLUE_CHAN, 1))
00758                                         set_flags(strip->lines[line]->flags, ASIM_SCL_BGDiffCalculated);
00759                         }
00760                 /* step 2. Calculating B-G for RG lines */
00761                 for (line = 0 ; line < strip->size ; ++line)
00762                         if (!get_flags(strip->lines[line]->flags, SCL_DO_BLUE)
00763                                 && !get_flags(strip->lines[line]->flags, ASIM_SCL_BGDiffCalculated))
00764                         {
00765                                 if (interpolate_green_diff(strip, line, ARGB32_BLUE_CHAN, 1))
00766                                         set_flags(strip->lines[line]->flags, ASIM_SCL_BGDiffCalculated);
00767                         }
00768                 /* step 3. Calculating BLUE from green + R-G */
00769                 for (line = 0 ; line < strip->size ; ++line)
00770                         if (get_flags(strip->lines[line]->flags, ASIM_SCL_BGDiffCalculated)
00771                             && !get_flags(strip->lines[line]->flags, (ASIM_SCL_InterpolatedAll<<ARGB32_BLUE_CHAN)))
00772                         {
00773                                 if (interpolate_from_green_diff(strip, line, ARGB32_BLUE_CHAN, 1))
00774                                         set_flags(strip->lines[line]->flags, SCL_DO_BLUE|(ASIM_SCL_InterpolatedAll<<ARGB32_BLUE_CHAN));
00775                         }
00776         }
00777 #endif
00778 
00779 }

Generated on Tue Jul 5 14:13:32 2011 for ROOT_528-00b_version by  doxygen 1.5.1