root/modules/rawhookops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. round_d2i
  2. rawop_get_cfa
  3. rawop_get_cfa_offsets
  4. rawop_get_bits_per_pixel
  5. rawop_get_raw_neutral
  6. rawop_get_black_level
  7. rawop_get_white_level
  8. rawop_get_raw_width
  9. rawop_get_raw_height
  10. rawop_get_active_left
  11. rawop_get_active_top
  12. rawop_get_active_width
  13. rawop_get_active_height
  14. rawop_get_jpeg_left
  15. rawop_get_jpeg_top
  16. rawop_get_jpeg_width
  17. rawop_get_jpeg_height
  18. rawop_get_pixel
  19. rawop_set_pixel
  20. rawop_get_pixels_rgbg
  21. rawop_set_pixels_rgbg
  22. rawop_fill_rect
  23. rawop_meter
  24. rawop_raw_to_ev
  25. rawop_ev_to_raw
  26. rawop_create_histogram
  27. rawop_histo_update
  28. rawop_histo_range
  29. rawop_histo_total_pixels
  30. rawop_histo_bits
  31. rawop_histo_free
  32. rawop_histo_gc
  33. init_raw_params
  34. rawop_update_hook_status
  35. luaopen_rawop

   1 /*
   2 functions for operating on raw framebuffer from script hooks
   3 */
   4 #include "camera_info.h"
   5 #include "stdlib.h"
   6 #include "conf.h"
   7 #include "raw.h"
   8 #include "math.h"
   9 
  10 #include "../lib/lua/lualib.h"
  11 #include "../lib/lua/lauxlib.h"
  12 
  13 extern void set_number_field(lua_State *L, const char *name, int value);
  14 
  15 // set when in hook and capture mode supports raw
  16 static int raw_buffer_valid;
  17 
  18 // TODO not really the same for R,G,B
  19 // raw value of a neutral exposure, including black level
  20 static unsigned raw_neutral;
  21 // log2(raw_neutral - blacklevel), i.e. the range of significant raw values
  22 static double log2_raw_neutral_count; 
  23 
  24 // offsets of bayer elements from an even pixel coordinate
  25 // [r,g,g,b][x,y]
  26 static unsigned cfa_offsets[4][2];
  27 static const char *cfa_names[]={"r","g1","g2","b"};
  28 #define CFA_R 0
  29 #define CFA_G1 1
  30 #define CFA_G2 2
  31 #define CFA_B 3
  32 #define RAWOP_HISTO_META "rawop.histo_meta"
  33 
  34 // simple round half away from zero
  35 static int round_d2i(double v) {
  36     if(v<0.0) {
  37         return (int)(v - 0.5);
  38     }
  39     return (int)(v + 0.5);
  40 }
  41 /*
  42 cfa=rawop.get_cfa()
  43 return: CFA pattern as a 32 bit interger, as used in DNG
  44 */
  45 static int rawop_get_cfa(lua_State *L) {
  46     lua_pushnumber(L,camera_sensor.cfa_pattern);
  47     return 1;
  48 }
  49 
  50 /*
  51 cfa_offsets=rawop.get_cfa_offsets()
  52 returns: offsets of color filter elements with respect to an even valued x,y pair, in the form
  53 {
  54  r={ y=1, x=0, },
  55  g1={ y=0, x=0, },
  56  b={ y=0, x=1, },
  57  g2={ y=1, x=1, },
  58 }
  59 */
  60 static int rawop_get_cfa_offsets(lua_State *L) {
  61     lua_createtable(L, 0, 4);
  62     int i;
  63     for(i=0;i<4;i++) {
  64         lua_createtable(L, 0, 2);
  65         set_number_field(L,"x",cfa_offsets[i][0]);
  66         set_number_field(L,"y",cfa_offsets[i][1]);
  67         lua_setfield(L, -2, cfa_names[i]);
  68     }
  69     return 1;
  70 }
  71 
  72 /*
  73 bpp=rawop.get_bits_per_pixel()
  74 returns: sensor bit depth (10, 12, or 14 in currently supported cameras)
  75 */
  76 static int rawop_get_bits_per_pixel(lua_State *L) {
  77     lua_pushnumber(L,camera_sensor.bits_per_pixel);
  78     return 1;
  79 }
  80 
  81 /*
  82 neutral=rawop.get_raw_neutral()
  83 returns: approximate raw value of a neutral grey target exposed with canon AE
  84 raw_to_ev96(netural) = 0
  85 This is not aware of CFA, it is based on an average of all color elements
  86 
  87 NOTE on G1x, the value may change depending on ISO settings. The value is only
  88 updated when the raw hook is entered for the shot so for maximum portability,
  89 this function should only be called inside the raw hook.
  90 */
  91 static int rawop_get_raw_neutral(lua_State *L) {
  92     lua_pushnumber(L,(int)raw_neutral);
  93     return 1;
  94 }
  95 
  96 /*
  97 bl=rawop.get_black_level()
  98 returns: sensor black level value
  99 
 100 NOTE on G1x, the value may change depending on ISO settings. The value is only
 101 updated when the raw hook is entered for the shot so for maximum portability,
 102 this function should only be called inside the raw hook.
 103 */
 104 static int rawop_get_black_level(lua_State *L) {
 105     lua_pushnumber(L,camera_sensor.black_level);
 106     return 1;
 107 }
 108 
 109 /*
 110 wl=rawop.get_white_level()
 111 returns: sensor white level value (2^bpp - 1 for all known sensors)
 112 */
 113 static int rawop_get_white_level(lua_State *L) {
 114     lua_pushnumber(L,camera_sensor.white_level);
 115     return 1;
 116 }
 117 
 118 /*
 119 w=rawop.get_raw_width()
 120 returns: width of the raw buffer, in pixels
 121 */
 122 static int rawop_get_raw_width(lua_State *L) {
 123     lua_pushnumber(L,camera_sensor.raw_rowpix);
 124     return 1;
 125 }
 126 
 127 /*
 128 h=rawop.get_raw_height()
 129 returns height of the raw buffer, in pixels
 130 */
 131 static int rawop_get_raw_height(lua_State *L) {
 132     lua_pushnumber(L,camera_sensor.raw_rows);
 133     return 1;
 134 }
 135 
 136 /*
 137 active area functions
 138 
 139 NOTES
 140 Active area is defined in the port, and is not affected by the "Crop size" DNG menu option
 141 
 142 Active area may include dark borders of pixels which contain image data, but are not exposed
 143 the same as the majority of the sensor. JPEG area may be a better choice for whole scene
 144 measurements.
 145 */
 146 
 147 /*
 148 left=rawop.get_active_left()
 149 returns: x coordinate of the leftmost pixel containing valid data in the raw buffer
 150 */
 151 static int rawop_get_active_left(lua_State *L) {
 152     lua_pushnumber(L,camera_sensor.active_area.x1);
 153     return 1;
 154 }
 155 
 156 /*
 157 top=rawop.get_active_top()
 158 returns: y coordinate of the topmost pixel containing valid data in the raw buffer
 159 */
 160 static int rawop_get_active_top(lua_State *L) {
 161     lua_pushnumber(L,camera_sensor.active_area.y1);
 162     return 1;
 163 }
 164 
 165 /*
 166 w=rawop.get_active_width()
 167 returns: width of the active area, in pixels
 168 */
 169 static int rawop_get_active_width(lua_State *L) {
 170     lua_pushnumber(L,camera_sensor.active_area.x2 - camera_sensor.active_area.x1);
 171     return 1;
 172 }
 173 
 174 /*
 175 h=rawop.get_active_height()
 176 returns: height of the active area, in pixels
 177 */
 178 static int rawop_get_active_height(lua_State *L) {
 179     lua_pushnumber(L,camera_sensor.active_area.y2 - camera_sensor.active_area.y1);
 180     return 1;
 181 }
 182 
 183 /*
 184 JPEG area functions
 185 
 186 NOTES
 187 JPEG area is defined in the port, and is not affected by the "Crop size" DNG menu option
 188 
 189 JPEG area represents the approximate area of the sensor used for the JPEG, but may not
 190 exactly match either the pixel dimensions or sensor area.
 191 
 192 These functions return sensor coordinates, not active area relative coordinates used
 193 in DNG metadata.
 194 
 195 JPEG area generally will not include the dark borders that can affect active area, so jpeg
 196 area is a good choice for measuring the whole scene.
 197 */
 198 
 199 /*
 200 left=rawop.get_jpeg_left()
 201 returns: x coordinate of the leftmost pixel of the jpeg area, in sensor coordinates
 202 */
 203 static int rawop_get_jpeg_left(lua_State *L) {
 204     lua_pushnumber(L,camera_sensor.active_area.x1 + camera_sensor.jpeg.x);
 205     return 1;
 206 }
 207 
 208 /*
 209 top=rawop.get_jpeg_top()
 210 returns: y coordinate of the topmost pixel of the jpeg area, in sensor coordinates
 211 */
 212 static int rawop_get_jpeg_top(lua_State *L) {
 213     lua_pushnumber(L,camera_sensor.active_area.y1 + camera_sensor.jpeg.y);
 214     return 1;
 215 }
 216 
 217 /*
 218 width=rawop.get_jpeg_width()
 219 returns: width of the jpeg area, in pixels
 220 */
 221 static int rawop_get_jpeg_width(lua_State *L) {
 222     lua_pushnumber(L,camera_sensor.jpeg.width);
 223     return 1;
 224 }
 225 
 226 /*
 227 height=rawop.get_jpeg_height()
 228 returns: height of the jpeg area, in pixels
 229 */
 230 static int rawop_get_jpeg_height(lua_State *L) {
 231     lua_pushnumber(L,camera_sensor.jpeg.height);
 232     return 1;
 233 }
 234 
 235 
 236 /*
 237 raw buffer access functions
 238 */
 239 /*
 240 v=rawop.get_pixel(x,y)
 241 return: raw value, or nil if out of bounds
 242 
 243 An error is generated if the this function is called outside the raw hook, or in a shooting
 244 mode for which raw data is not available.
 245 */
 246 static int rawop_get_pixel(lua_State *L) {
 247     if(!raw_buffer_valid) {
 248         return luaL_error(L,"raw data not available");
 249     }
 250     unsigned x=luaL_checknumber(L,1);
 251     unsigned y=luaL_checknumber(L,2);
 252     // TODO return nil for out of bounds?
 253     // might not want to check, or return 0, or error()?
 254     if(x >= (unsigned)camera_sensor.raw_rowpix || y >= (unsigned)camera_sensor.raw_rows) {
 255         return 0;
 256     }
 257     lua_pushnumber(L,get_raw_pixel(x,y));
 258     return 1;
 259 }
 260 
 261 /*
 262 rawop.set_pixel(x,y,v)
 263 sets pixel to v
 264 
 265 An error is generated if the this function is called outside the raw hook, or in a shooting
 266 mode for which raw data is not available.
 267 */
 268 static int rawop_set_pixel(lua_State *L) {
 269     if(!raw_buffer_valid) {
 270         return luaL_error(L,"raw data not available");
 271     }
 272     unsigned int x=luaL_checknumber(L,1);
 273     unsigned int y=luaL_checknumber(L,2);
 274     unsigned short v=luaL_checknumber(L,3);
 275     // TODO
 276     // might want to or error()?
 277     if(x >= (unsigned)camera_sensor.raw_rowpix || y >= (unsigned)camera_sensor.raw_rows) {
 278         return 0;
 279     }
 280     // TODO could check v
 281     set_raw_pixel(x,y,v);
 282     return 0;
 283 }
 284 
 285 /*
 286 r,g1,b,g2=rawop.get_pixels_rgbg(x,y)
 287 returns: values of the CFA quad containing x,y or nil if out of bounds
 288 x and y are truncated to the nearest even value.
 289 
 290 An error is generated if the this function is called outside the raw hook, or in a shooting
 291 mode for which raw data is not available.
 292 */
 293 static int rawop_get_pixels_rgbg(lua_State *L) {
 294     if(!raw_buffer_valid) {
 295         return luaL_error(L,"raw data not available");
 296     }
 297     unsigned int x=luaL_checknumber(L,1);
 298     unsigned int y=luaL_checknumber(L,2);
 299 
 300     x &= 0xFFFFFFFE;
 301     y &= 0xFFFFFFFE;
 302 
 303     if(x >= (unsigned)camera_sensor.raw_rowpix || y >= (unsigned)camera_sensor.raw_rows) {
 304         return 0;
 305     }
 306     lua_pushnumber(L,get_raw_pixel(x+cfa_offsets[CFA_R][0],y+cfa_offsets[CFA_R][1]));
 307     lua_pushnumber(L,get_raw_pixel(x+cfa_offsets[CFA_G1][0],y+cfa_offsets[CFA_G1][1]));
 308     lua_pushnumber(L,get_raw_pixel(x+cfa_offsets[CFA_B][0],y+cfa_offsets[CFA_B][1]));
 309     lua_pushnumber(L,get_raw_pixel(x+cfa_offsets[CFA_G2][0],y+cfa_offsets[CFA_G2][1]));
 310     return 4;
 311 }
 312 
 313 /*
 314 rawop.set_pixels_rgbg(x,y,r,g1,b[,g2])
 315 sets the values of the CFA quad containing x,y
 316 if g2 is not specified, it is set to g1
 317 x and y are truncated to the nearest even value.
 318 
 319 An error is generated if the this function is called outside the raw hook, or in a shooting
 320 mode for which raw data is not available.
 321 */
 322 static int rawop_set_pixels_rgbg(lua_State *L) {
 323     if(!raw_buffer_valid) {
 324         return luaL_error(L,"raw data not available");
 325     }
 326     unsigned int x=luaL_checknumber(L,1);
 327     unsigned int y=luaL_checknumber(L,2);
 328     unsigned short r=luaL_checknumber(L,3);
 329     unsigned short g1=luaL_checknumber(L,4);
 330     unsigned short b=luaL_checknumber(L,5);
 331     unsigned short g2=luaL_optnumber(L,6,g1);
 332 
 333     x &= 0xFFFFFFFE;
 334     y &= 0xFFFFFFFE;
 335 
 336     if(x >= (unsigned)camera_sensor.raw_rowpix - 1 || y >= (unsigned)camera_sensor.raw_rows - 1) {
 337         return 0;
 338     }
 339     set_raw_pixel(x+cfa_offsets[CFA_R][0],y+cfa_offsets[CFA_R][1],r);
 340     set_raw_pixel(x+cfa_offsets[CFA_G1][0],y+cfa_offsets[CFA_G1][1],g1);
 341     set_raw_pixel(x+cfa_offsets[CFA_B][0],y+cfa_offsets[CFA_B][1],b);
 342     set_raw_pixel(x+cfa_offsets[CFA_G2][0],y+cfa_offsets[CFA_G2][1],g2);
 343     return 0;
 344 }
 345 
 346 /*
 347 rawop.fill_rect(x,y,width,height,val[,xstep[,ystep]])
 348 sets every step-th pixel of the specified rectangle to the specified value
 349 width and height out of bounds are clipped
 350 xstep defaults to 1, ystep defaults to xstep
 351 step 2 can be used with cfa offsets to fill RGB
 352 
 353 An error is generated if the this function is called outside the raw hook, or in a shooting
 354 mode for which raw data is not available.
 355 */
 356 static int rawop_fill_rect(lua_State *L) {
 357     if(!raw_buffer_valid) {
 358         return luaL_error(L,"raw data not available");
 359     }
 360     unsigned int xstart=luaL_checknumber(L,1);
 361     unsigned int ystart=luaL_checknumber(L,2);
 362     unsigned int width=luaL_checknumber(L,3);
 363     unsigned int height=luaL_checknumber(L,4);
 364     unsigned short val=luaL_checknumber(L,5);
 365     unsigned int xstep=luaL_optnumber(L,6,1);
 366     unsigned int ystep=luaL_optnumber(L,7,xstep);
 367     unsigned int xmax = xstart + width;
 368     unsigned int ymax = ystart + height;
 369     if(xstart >= (unsigned)camera_sensor.raw_rowpix || ystart >= (unsigned)camera_sensor.raw_rows) {
 370         return 0;
 371     }
 372     if(xmax > (unsigned)camera_sensor.raw_rowpix) {
 373         xmax = (unsigned)camera_sensor.raw_rowpix; 
 374     }
 375     if(ymax > (unsigned)camera_sensor.raw_rows) {
 376         ymax = (unsigned)camera_sensor.raw_rows;
 377     }
 378     int x,y;
 379     for(y=ystart; y<ymax; y+=ystep) {
 380         for(x=xstart; x<xmax; x+=xstep) {
 381             set_raw_pixel(x,y,val);
 382         }
 383     }
 384     return 0;
 385 }
 386 
 387 /*
 388 mean_raw_val=rawop.meter(x,y,x_count,y_count,x_step,y_step)
 389 returns: average values of count pixels in x and y, sampled at step size step,
 390 or nil if the range is invalid or the total number of pixels could result in overflow
 391 
 392 An error is generated if the this function is called outside the raw hook, or in a shooting
 393 mode for which raw data is not available.
 394 
 395 To prevent overflow, the total number of pixels must less unsigned_max / white_level.
 396 Limits are roughly 
 397 10 bpp = 4 Mpix
 398 12 bpp = 1 Mpix
 399 14 bpp = 256 Kpix
 400 To meter larger numbers of pixels, use multiple calls and average the results
 401 
 402 To meter R G B separately, use multiple meter calls with the appropriate CFA offset and even steps
 403 To ensure all CFA colors are included in a single call, use odd steps
 404 */
 405 static int rawop_meter(lua_State *L) {
 406     if(!raw_buffer_valid) {
 407         return luaL_error(L,"raw data not available");
 408     }
 409     unsigned x1=luaL_checknumber(L,1);
 410     unsigned y1=luaL_checknumber(L,2);
 411     unsigned x_count=luaL_checknumber(L,3);
 412     unsigned y_count=luaL_checknumber(L,4);
 413     unsigned x_step=luaL_checknumber(L,5);
 414     unsigned y_step=luaL_checknumber(L,6);
 415 
 416     // no pixels
 417     if(!x_count || !y_count) {
 418         return 0;
 419     }
 420 
 421     unsigned x_max = x1 + x_step * x_count;
 422     unsigned y_max = y1 + y_step * y_count;
 423     // x out of range
 424     if(x_max > (unsigned)camera_sensor.raw_rowpix) {
 425         return 0;
 426     }
 427     // y out of range
 428     if(y_max > (unsigned)camera_sensor.raw_rows) {
 429         return 0;
 430     }
 431     // overflow possible (int max)/total  < max value 
 432     if(x_count*y_count > (unsigned)0xFFFFFFFF >> camera_sensor.bits_per_pixel) {
 433         return 0;
 434     }
 435     unsigned t=0;
 436     unsigned x,y;
 437     for(y = y1; y < y_max; y += y_step) {
 438         for(x = x1; x < x_max; x += x_step) {
 439             t+=get_raw_pixel(x,y);
 440         }
 441     }
 442     lua_pushnumber(L,t/(x_count*y_count));
 443     return 1;
 444 }
 445 
 446 /*
 447 raw value conversion functions
 448 */
 449 /*
 450 ev96=rawop.raw_to_ev(rawval[,scale])
 451 convert a raw value (blacklevel+1 to whitelevel) into an APEX EV relative to neutral
 452 if rawval is <= to blacklevel, it is clamped to blacklevel + 1.
 453 values > whitelevel are converted normally
 454 
 455 scale optionally scales the APEX value, default 96 to be compatible with camera
 456 exposure parameters. Use 1000 for imath APEX values or 96000 for APEX96 with imath
 457 
 458 NOTE on G1x, the result may change depending on ISO settings. The value is only
 459 updated when the raw hook is entered for the shot so for maximum portability,
 460 this function should only be called inside the raw hook.
 461 */
 462 static int rawop_raw_to_ev(lua_State *L) {
 463     int v=luaL_checknumber(L,1);
 464     int scale=luaL_optnumber(L,2,96);
 465     // TODO not clear what we should return, minimum real value for now
 466     if( v <= camera_sensor.black_level) {
 467         v = camera_sensor.black_level+1;
 468     }
 469     int r=round_d2i((double)scale*(log2(v - camera_sensor.black_level) - log2_raw_neutral_count));
 470     lua_pushnumber(L,r);
 471     return 1;
 472 }
 473 
 474 /*
 475 rawval=rawop.ev_to_raw(ev[,scale])
 476 Convert an APEX EV (offset from raw_neutral) to a raw value. No range checking is done
 477 
 478 scale optionally scales the APEX value, default 96 to be compatible with camera
 479 exposure parameters. Use 1000 for imath or 96000 for APEX96 with imath
 480 
 481 NOTE on G1x, the result may change depending on ISO settings. The value is only
 482 updated when the raw hook is entered for the shot so for maximum portability,
 483 this function should only be called inside the raw hook.
 484 */
 485 static int rawop_ev_to_raw(lua_State *L) {
 486     int v=luaL_checknumber(L,1);
 487     int scale=luaL_optnumber(L,2,96);
 488     // TODO not clear if this should be clamped to valid raw ranges?
 489     lua_pushnumber(L,round_d2i(pow(2,(double)v/(double)scale+log2_raw_neutral_count)+camera_sensor.black_level));
 490     return 1;
 491 }
 492 
 493 
 494 /*
 495 histogram functions and methods
 496 */
 497 typedef struct {
 498     unsigned bits;
 499     unsigned entries;
 500     unsigned total_pixels;
 501     unsigned *data;
 502 } rawop_histo_t;
 503 /*
 504 create new histogram object
 505 histo=rawop.create_histogram()
 506 */
 507 static int rawop_create_histogram(lua_State *L) {
 508     rawop_histo_t *h = (rawop_histo_t *)lua_newuserdata(L,sizeof(rawop_histo_t));
 509     if(!h) {
 510         return luaL_error(L,"failed to create userdata");
 511     }
 512     h->total_pixels = 0;
 513     h->data = NULL;
 514     luaL_getmetatable(L, RAWOP_HISTO_META);
 515     lua_setmetatable(L, -2);
 516     return 1;
 517 }
 518 
 519 /*
 520 update histogram data using specified area of raw buffer
 521 histo:update(top,left,width,height,xstep,ystep[,bits])
 522 bits specifies the bit depth of histogram. defaults to camera bit depth
 523 must be <= camera bit depth
 524 amount of memory required for the histogram data is determined by bits
 525 
 526 An error is generated if the this function is called outside the raw hook, or in a shooting
 527 mode for which raw data is not available.
 528 */
 529 static int rawop_histo_update(lua_State *L) {
 530     if(!raw_buffer_valid) {
 531         return luaL_error(L,"raw data not available");
 532     }
 533     rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
 534 
 535     unsigned xstart=luaL_checknumber(L,2);
 536     unsigned ystart=luaL_checknumber(L,3);
 537     unsigned width=luaL_checknumber(L,4);
 538     unsigned height=luaL_checknumber(L,5);
 539     unsigned xstep=luaL_checknumber(L,6);
 540     unsigned ystep=luaL_checknumber(L,7);
 541     unsigned bits=luaL_optnumber(L,8,camera_sensor.bits_per_pixel);
 542     if(bits > camera_sensor.bits_per_pixel || bits < 1) {
 543         return luaL_error(L,"invalid bit depth");
 544     }
 545     unsigned shift = camera_sensor.bits_per_pixel - bits;
 546     unsigned entries = 1 << bits;
 547 
 548     h->total_pixels=0;
 549     if(xstart >= (unsigned)camera_sensor.raw_rowpix 
 550         || ystart >= (unsigned)camera_sensor.raw_rows
 551         || xstep == 0 || ystep == 0
 552         || width == 0 || height == 0) {
 553         luaL_error(L,"invalid update area");
 554         return 0;
 555     }
 556     unsigned xmax=xstart+width;
 557     unsigned ymax=ystart+height;
 558     if(xmax > (unsigned)camera_sensor.raw_rowpix) {
 559         xmax = (unsigned)camera_sensor.raw_rowpix; 
 560     }
 561     if(ymax > (unsigned)camera_sensor.raw_rows) {
 562         ymax = (unsigned)camera_sensor.raw_rows;
 563     }
 564     // total with clipping and rounding accounted for
 565     h->total_pixels=((1+(xmax - xstart - 1)/xstep))*((1+(ymax - ystart - 1)/ystep));
 566 
 567     // TODO shorts or ints based on total pixels
 568     if(h->entries != entries || !h->data) {
 569         free(h->data);
 570         h->data = malloc(entries*sizeof(unsigned));
 571         if(!h->data) {
 572             h->total_pixels=0;
 573             return luaL_error(L,"insufficient memory");
 574         }
 575     }
 576     h->entries = entries;
 577     h->bits = bits;
 578     memset(h->data,0,h->entries*sizeof(unsigned));
 579 
 580     unsigned x,y;
 581     if(shift) {
 582         for(y=ystart;y<ymax;y+=ystep) {
 583             for(x=xstart;x<xmax;x+=xstep) {
 584                 h->data[get_raw_pixel(x,y)>>shift]++;
 585             }
 586         }
 587     } else {
 588         for(y=ystart;y<ymax;y+=ystep) {
 589             for(x=xstart;x<xmax;x+=xstep) {
 590                 h->data[get_raw_pixel(x,y)]++;
 591             }
 592         }
 593     }
 594     return 0;
 595 }
 596 
 597 /*
 598 frac=histo:range(min,max[,'count'|scale])
 599 returns number of values in range, either as a fraction in parts per scale, or total count
 600 */
 601 static int rawop_histo_range(lua_State *L) {
 602     rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
 603     if(!h->data) {
 604         return luaL_error(L,"no data");
 605     }
 606     unsigned minval=luaL_checknumber(L,2);
 607     unsigned maxval=luaL_checknumber(L,3);
 608     int scale=1000;
 609     if(lua_gettop(L) >= 4 && !lua_isnil(L,4)) {
 610         const char *s=lua_tostring(L,4);
 611         if(!s || strcmp(s,"count") != 0) {
 612             scale=lua_tonumber(L,4);
 613             // scale could be 0 from error passing 0, but neither is valid
 614             if(!scale) {
 615                 return luaL_error(L,"invalid format");
 616             }
 617         } else {
 618             scale=0;
 619         }
 620     }
 621     if(maxval >= h->entries || minval > maxval) {
 622         return luaL_error(L,"invalid range");
 623     }
 624     // TODO error?
 625     if(!h->total_pixels) {
 626         return luaL_error(L,"no pixels");
 627 //        lua_pushnumber(L,0);
 628 //        return 1;
 629     }
 630 
 631     unsigned count=0;
 632     int i;
 633     for(i=minval;i<=maxval;i++) {
 634         count+=h->data[i];
 635     }
 636     // TODO full raw buffer count*1000 could overflow 32 bit int
 637     // could check / work around using ints but probably not worth it
 638     if(scale) {
 639         lua_pushnumber(L,round_d2i((scale*(double)count)/(double)h->total_pixels));
 640     } else {
 641         lua_pushnumber(L,count);
 642     }
 643     return 1;
 644 }
 645 
 646 /*
 647 total=histo:total_pixels()
 648 returns: total number of pixels sampled
 649 */
 650 static int rawop_histo_total_pixels(lua_State *L) {
 651     rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
 652     if(!h->data) {
 653         return luaL_error(L,"no data");
 654     }
 655     lua_pushnumber(L,h->total_pixels);
 656     return 1;
 657 }
 658 
 659 /*
 660 bits=histo:bits()
 661 returns bit depth of histogram
 662 */
 663 static int rawop_histo_bits(lua_State *L) {
 664     rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
 665     if(!h->data) {
 666         return luaL_error(L,"no data");
 667     }
 668     lua_pushnumber(L,h->bits);
 669     return 1;
 670 }
 671 
 672 /*
 673 histo:free()
 674 free memory used by histogram data. histo:update must be called again to before any other functions
 675 */
 676 static int rawop_histo_free(lua_State *L) {
 677     rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
 678     free(h->data);
 679     h->data=NULL;
 680     return 0;
 681 }
 682 
 683 static int rawop_histo_gc(lua_State *L) {
 684     rawop_histo_free(L);
 685     return 0;
 686 }
 687 
 688 static const luaL_Reg rawop_histo_meta_methods[] = {
 689   {"__gc", rawop_histo_gc},
 690   {NULL, NULL}
 691 };
 692 
 693 static const luaL_Reg rawop_histo_methods[] = {
 694   {"update", rawop_histo_update},
 695   {"range", rawop_histo_range},
 696   {"total_pixels", rawop_histo_total_pixels},
 697   {"bits", rawop_histo_bits},
 698   {"free", rawop_histo_free},
 699   {NULL, NULL}
 700 };
 701 
 702 static const luaL_Reg rawop_funcs[] = {
 703   // general raw characteristics
 704   {"get_cfa",           rawop_get_cfa},
 705   {"get_cfa_offsets",   rawop_get_cfa_offsets},
 706   {"get_bits_per_pixel",rawop_get_bits_per_pixel},
 707   {"get_raw_neutral",   rawop_get_raw_neutral},
 708   {"get_black_level",   rawop_get_black_level},
 709   {"get_white_level",   rawop_get_white_level},
 710 
 711   // buffer sizes
 712   {"get_raw_width",     rawop_get_raw_width},
 713   {"get_raw_height",    rawop_get_raw_height},
 714   {"get_active_left",   rawop_get_active_left},
 715   {"get_active_top",    rawop_get_active_top},
 716   {"get_active_width",  rawop_get_active_width},
 717   {"get_active_height", rawop_get_active_height},
 718   {"get_jpeg_left",     rawop_get_jpeg_left},
 719   {"get_jpeg_top",      rawop_get_jpeg_top},
 720   {"get_jpeg_width",    rawop_get_jpeg_width},
 721   {"get_jpeg_height",   rawop_get_jpeg_height},
 722 
 723   // raw buffer access
 724   {"get_pixel",         rawop_get_pixel},
 725   {"set_pixel",         rawop_set_pixel},
 726   {"get_pixels_rgbg",   rawop_get_pixels_rgbg},
 727   {"set_pixels_rgbg",   rawop_set_pixels_rgbg},
 728   {"fill_rect",         rawop_fill_rect},
 729   {"meter",             rawop_meter},
 730 
 731   // value conversion
 732   {"raw_to_ev",         rawop_raw_to_ev},
 733   {"ev_to_raw",         rawop_ev_to_raw},
 734 
 735   // histogram
 736   {"create_histogram",  rawop_create_histogram},
 737   {NULL, NULL}
 738 };
 739 
 740 // initialize raw params that may change between frames (currently neutral and related values)
 741 // could update only if changed, but not needed
 742 static void init_raw_params(void) {
 743     // empirical guestimate
 744     // average pixel value of a neutral subject shot with canon AE, as a fraction of usable dynamic range
 745     // found to be reasonably close on d10, elph130, a540, g1x and more.
 746     double raw_neutral_count = (double)(camera_sensor.white_level - camera_sensor.black_level)/(6.669);
 747     log2_raw_neutral_count = log2(raw_neutral_count);
 748     raw_neutral = round_d2i(raw_neutral_count) + camera_sensor.black_level;
 749 }
 750 
 751 // update values that need to be updated when hook becomes active
 752 void rawop_update_hook_status(int active) {
 753     if(active) {
 754         raw_buffer_valid = is_raw_possible();
 755         init_raw_params();
 756     } else {
 757         raw_buffer_valid = 0;
 758     }
 759 }
 760 
 761 int luaopen_rawop(lua_State *L) {
 762     // initialize globals
 763     raw_buffer_valid = 0;
 764 
 765     int i;
 766     int g1=1;
 767     for(i=0; i<4; i++) {
 768         int c = (camera_sensor.cfa_pattern >> 8*i) & 0xFF;
 769         int ci=0;
 770         switch(c) {
 771             case 0:
 772                 ci=0;
 773             break;
 774             case 1:
 775                 if(g1) {
 776                     ci=1;
 777                     g1=0;
 778                 } else {
 779                     ci=2;
 780                 }
 781             break;
 782             case 2:
 783                 ci=3;
 784             break;
 785         }
 786         cfa_offsets[ci][0] = i&1;
 787         cfa_offsets[ci][1] = (i&2)>>1;
 788     }
 789 
 790     // TODO - maybe this should only be done in update_hook_status, since any changeable values
 791     // will only be known at that point.
 792     init_raw_params();
 793 
 794     luaL_newmetatable(L,RAWOP_HISTO_META);
 795     luaL_register(L, NULL, rawop_histo_meta_methods);  
 796     /* use a table of methods for the __index method */
 797     lua_newtable(L);
 798     luaL_register(L, NULL, rawop_histo_methods);  
 799     lua_setfield(L,-2,"__index");
 800     lua_pop(L,1);
 801 
 802     /* global lib*/
 803     lua_newtable(L);
 804     luaL_register(L, "rawop", rawop_funcs);  
 805     return 1;
 806 }

/* [<][>][^][v][top][bottom][index][help] */