Logo Search packages:      
Sourcecode: libgphoto2 version File versions

lmini_ccd.c

/*
 * This file convert raw CCD bitmaps to BMP. Used for thumbnails.
 * Code probably grafted from Largan Lmini SDK.
 */

#include <string.h>

#include "lmini_ccd.h"


static void fetchstr(int, int, int);
static void dhuf(int);
static void YCbCr2RGB(int *YY, int Cb, int Cr, int w, int h);

static int _nCcdFactor = 1;

static char *data;

static long out_index;
static long count;
static int  in_bit;

static unsigned char BUFF11[14400];

static unsigned long in_string;
static int  pre_y, pre_cb, pre_cr;

static int y[7446];

static const int y_max[10]= {
      0x0,  0x0,  0x0,  0x6,
      0xe,  0x1e, 0x3e, 0x7e,
      0xfe, 0x1fe,
      };

static const int y_min[10]= {
      0x0,  0x0,  0x0,  0x2,
      0xe,  0x1e, 0x3e, 0x7e,
      0xfe, 0x1fe,
      };

static const int uv_max[12]= {
      0x0,  0x0,   0x2,   0x6,
      0xe,  0x1e,  0x3e,  0x7e,
      0xfe, 0x1fe, 0x3fe, 0x7fe
      };

static const int uv_min[12]= {
      0x0,  0x0,   0x0,   0x6,
      0xe,  0x1e,  0x3e,  0x7e,
      0xfe, 0x1fe, 0x3fe, 0x7fe
      };


/* --------------------------------------------------------------------------- */
void largan_ccd2dib(char *pData, char *pDib, long dwDibRowBytes, int nCcdFactor)
{
    int i, j, w, h;
    int YY[4], Cb, Cr;

    _nCcdFactor = nCcdFactor;

    data = pData;

/************************************************/

    Cb = 0;
    Cr = 0;

    pre_y = 0;
    pre_cb = 0;
    pre_cr = 0;

    in_string = (*data << 8) | *(data + 1);

    in_bit = 16;
    count = 2;
    out_index = 0;
/******************************************************/

    for (j = 0; j < 1200; j++)
{
      for (i = 0; i < 4; i++)
          dhuf(0);

      dhuf(1);
      dhuf(2);
      }

    /* printf("Now process the DC term to R G B transfer !\n"); */

    for (h = 0; h < 30; h++) /* mini size height = 30 x 2 */
      {
      for (w = 0; w < 40; w++)
          {
          for (i = 0; i < 6; i++)
            {
            int   k = i + w * 6 + h * 240;

            if (i < 4)
                YY[i] = y[k] * _nCcdFactor;
            else if (i == 4)
                Cb = y[k] * _nCcdFactor;
            else if (i == 5)
                Cr = y[k] * _nCcdFactor;
            }

          YCbCr2RGB(YY, Cb, Cr, w, h);
          }
      }

    for (i = 0, j = 0; i < 60; i++, j += 240)
      {
      memcpy (pDib, &BUFF11[j], 240);
      pDib -= dwDibRowBytes;
      }
}

/* --------------------------------------------------------------------------- */
static void YCbCr2RGB(int *YY, int Cb, int Cr, int w, int h)
{
    int     i;
    double  B,G,R;
    double  c2 = 1.7753, c3 = -0.0015;
    double  c5 = -0.3443, c6 = -0.7137;
    double  c8 = -0.0009, c9 = 1.4017;

    for (i = 0; i < 2; i++)
      {
      int   k = 3 * i + w * 6 + h * 480;

      B = ((double) YY[i] + 128.0 + c2 * Cb + c3 * Cr) + 0.5;
      if (B > 255)
         B = 255;
      else if (B < 0)
         B = 0;
      BUFF11[k] = (unsigned char) B;

      G = ((double) YY[i] + 128.0 + c5 * Cb + c6 * Cr) + 0.5;
      if (G > 255)
         G = 255;
      else if (G < 0)
         G = 0;
      BUFF11[k + 1] = (unsigned char) G;

      R = ((double) YY[i] + 128.0 + c8 * Cb + c9 * Cr) + 0.5;
      if (R > 255)
         R = 255;
      else if (R < 0)
         R = 0;
      BUFF11[k + 2] = (unsigned char) R;
      }

    for (i = 0; i < 2; i++)
      {
      int   k = 3 * i + w * 6 + h * 480 + 240;

      B = ((double) YY[i + 2] + 128.0 + c2 * Cb + c3 * Cr) + 0.5;
      if (B > 255)
         B = 255;
      else if (B < 0)
         B = 0;
      BUFF11[k] = (unsigned char) B;

      G = ((double) YY[i + 2] + 128.0 + c5 * Cb + c6 * Cr) + 0.5;
      if (G > 255)
         G = 255;
      else if (G < 0)
         G = 0;
      BUFF11[k + 1] = (unsigned char) G;

      R = ((double) YY[i + 2] + 128.0 + c8 * Cb + c9 * Cr) + 0.5;
      if (R > 255)
         R = 255;
      else if (R < 0)
         R = 0;
      BUFF11[k + 2] = (unsigned char) R;
      }
}

/* --------------------------------------------------------------------------- */
static void dhuf(int flag)
{
    int     code_leng, val_leng;
    int    temp_s;
    int    temp;
    int     temp1;

    code_leng = 2;
    val_leng = 0;
    temp_s = (int) in_string;
    temp_s >>= 14;

    if (flag == 0)
      {
      while (((int)temp_s > y_max[code_leng]) || ((int)temp_s < y_min[code_leng]))
          {
          code_leng++;
          temp_s = (int) in_string;
          temp_s >>= (16 - code_leng);
          }
      }
    else
      {
      while (((int)temp_s > uv_max[code_leng]) || ((int)temp_s < uv_min[code_leng]))
          {
          code_leng++;
          temp_s = (int) in_string;
          temp_s >>= (16 - code_leng);
          }
      }

    temp = (int) in_string;
    temp >>= (16 - code_leng);
    temp1 = (int) temp;

    fetchstr(code_leng, 0, flag);

    if (flag == 0)
      {
      if (code_leng == 3)
          {
          switch (temp1)
            {
            case 2 : val_leng = 1; break;
            case 3 : val_leng = 2; break;
            case 4 : val_leng = 3; break;
            case 5 : val_leng = 4; break;
            case 6 : val_leng = 5; break;
            default: break;
            }
          }
      else if (code_leng == 2)
          val_leng = 0;
      else
          val_leng = code_leng + 2;
      }
    else
      {
      if (code_leng == 2)
          {
          switch (temp1)
            {
            case 0 : val_leng = 0; break;
            case 1 : val_leng = 1; break;
            case 2 : val_leng = 2; break;
            default: break;
            }
          }
      else
          val_leng = code_leng;
      }

    fetchstr(val_leng, 1, flag);
}


/* --------------------------------------------------------------------------- */
static void fetchstr(int shift_bit, int val_flag, int flag)
{
    int    temp_val;
    int     value1, value2;
    int     temp = 0;

    temp_val = (int) in_string;
    temp_val >>= (16 - shift_bit);
    in_string <<= shift_bit;
    in_bit -= shift_bit;

    if ((val_flag == 1) && (shift_bit == 0))
      {
      if (flag == 0)
          temp = pre_y;
      else if (flag == 1)
          temp = pre_cb;
      else if (flag == 2)
          temp = pre_cr;

      y[out_index] = temp;
      out_index++;
      }

    if ((val_flag == 1) && (shift_bit != 0))
      {
      value1 = (int) temp_val;
      value2 = value1;
      value2 &= (1 << (shift_bit - 1));

      if (value2 != 0)
          {
          if (flag == 0)
            {
            pre_y += value1;
            temp = pre_y;
            }
          else if (flag == 1)
            {
            pre_cb += value1;
            temp = pre_cb;
            }
          else if (flag == 2)
            {
            pre_cr += value1;
            temp=pre_cr;
            }

          y[out_index] = temp;
          out_index++;
          }
      else
          {
          value1++;
          value1 = -value1;

          value1 &= ((1 << shift_bit) - 1);
          value1 = -value1;

          if (flag == 0)
            {
            pre_y += value1;
            temp = pre_y;
            }
          else if (flag == 1)
            {
            pre_cb += value1;
            temp = pre_cb;
            }
          else if (flag == 2)
            {
            pre_cr +=value1;
            temp = pre_cr;
            }

          y[out_index] = temp;
          out_index++;
          }
      }

    while (in_bit <= 8)
      {
      in_string = in_string | (*(data + count) << (8 - in_bit));
      in_bit += 8;
      count++;
      }
}


Generated by  Doxygen 1.6.0   Back to index