/* * 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++; } }