#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h> typedef enum {
DC1394_BAYER_METHOD_NEAREST=,
DC1394_BAYER_METHOD_SIMPLE,
DC1394_BAYER_METHOD_BILINEAR,
DC1394_BAYER_METHOD_HQLINEAR,
DC1394_BAYER_METHOD_DOWNSAMPLE,
DC1394_BAYER_METHOD_EDGESENSE,
DC1394_BAYER_METHOD_VNG,
DC1394_BAYER_METHOD_AHD
} dc1394bayer_method_t; typedef enum {
DC1394_COLOR_FILTER_RGGB = ,
DC1394_COLOR_FILTER_GBRG,
DC1394_COLOR_FILTER_GRBG,
DC1394_COLOR_FILTER_BGGR
} dc1394color_filter_t ;
#define DC1394_COLOR_FILTER_MIN DC1394_COLOR_FILTER_RGGB
#define DC1394_COLOR_FILTER_MAX DC1394_COLOR_FILTER_BGGR
#define DC1394_COLOR_FILTER_NUM (DC1394_COLOR_FILTER_MAX - DC1394_COLOR_FILTER_MIN + 1) /**
* Error codes returned by most libdc1394 functions.
*
* General rule: 0 is success, negative denotes a problem.
*/
typedef enum {
DC1394_SUCCESS = ,
DC1394_FAILURE = -,
DC1394_NOT_A_CAMERA = -,
DC1394_FUNCTION_NOT_SUPPORTED = -,
DC1394_CAMERA_NOT_INITIALIZED = -,
DC1394_MEMORY_ALLOCATION_FAILURE = -,
DC1394_TAGGED_REGISTER_NOT_FOUND = -,
DC1394_NO_ISO_CHANNEL = -,
DC1394_NO_BANDWIDTH = -,
DC1394_IOCTL_FAILURE = -,
DC1394_CAPTURE_IS_NOT_SET = -,
DC1394_CAPTURE_IS_RUNNING = -,
DC1394_RAW1394_FAILURE = -,
DC1394_FORMAT7_ERROR_FLAG_1 = -,
DC1394_FORMAT7_ERROR_FLAG_2 = -,
DC1394_INVALID_ARGUMENT_VALUE = -,
DC1394_REQ_VALUE_OUTSIDE_RANGE = -,
DC1394_INVALID_FEATURE = -,
DC1394_INVALID_VIDEO_FORMAT = -,
DC1394_INVALID_VIDEO_MODE = -,
DC1394_INVALID_FRAMERATE = -,
DC1394_INVALID_TRIGGER_MODE = -,
DC1394_INVALID_TRIGGER_SOURCE = -,
DC1394_INVALID_ISO_SPEED = -,
DC1394_INVALID_IIDC_VERSION = -,
DC1394_INVALID_COLOR_CODING = -,
DC1394_INVALID_COLOR_FILTER = -,
DC1394_INVALID_CAPTURE_POLICY = -,
DC1394_INVALID_ERROR_CODE = -,
DC1394_INVALID_BAYER_METHOD = -,
DC1394_INVALID_VIDEO1394_DEVICE = -,
DC1394_INVALID_OPERATION_MODE = -,
DC1394_INVALID_TRIGGER_POLARITY = -,
DC1394_INVALID_FEATURE_MODE = -,
DC1394_INVALID_LOG_TYPE = -,
DC1394_INVALID_BYTE_ORDER = -,
DC1394_INVALID_STEREO_METHOD = -,
DC1394_BASLER_NO_MORE_SFF_CHUNKS = -,
DC1394_BASLER_CORRUPTED_SFF_CHUNK = -,
DC1394_BASLER_UNKNOWN_SFF_CHUNK = -
} dc1394error_t;
#define DC1394_ERROR_MIN DC1394_BASLER_UNKNOWN_SFF_CHUNK
#define DC1394_ERROR_MAX DC1394_SUCCESS
#define DC1394_ERROR_NUM (DC1394_ERROR_MAX-DC1394_ERROR_MIN+1) typedef enum {
DC1394_FALSE= ,
DC1394_TRUE
} dc1394bool_t; #define CLIP(in, out)\
in = in < ? : in;\
in = in > ? : in;\
out=in; #define CLIP16(in, out, bits)\
in = in < ? : in;\
in = in > ((<<bits)-) ? ((<<bits)-) : in;\
out=in; void ClearBorders(uint8_t *rgb, int sx, int sy, int w)
{
int i, j;
// black edges are added with a width w:
i = * sx * w - ;
j = * sx * sy - ;
while (i >= )
{
rgb[i--] = ;
rgb[j--] = ;
} int low = sx * (w - ) * - + w * ;
i = low + sx * (sy - w * + ) * ;
while (i > low)
{
j = * w;
while (j > )
{
rgb[i--] = ;
j--;
}
i -= (sx - * w) * ;
}
} void ClearBorders_uint16(uint16_t *rgb, int sx, int sy, int w)
{
int i, j; // black edges:
i = * sx * w - ;
j = * sx * sy - ;
while (i >= )
{
rgb[i--] = ;
rgb[j--] = ;
} int low = sx * (w - ) * - + w * ;
i = low + sx * (sy - w * + ) * ;
while (i > low)
{
j = * w;
while (j > )
{
rgb[i--] = ;
j--;
}
i -= (sx - * w) * ;
} } /**************************************************************
* Color conversion functions for cameras that can *
* output raw-Bayer pattern images, such as some Basler and *
* Point Grey camera. Most of the algos presented here come *
* from http://www-ise.stanford.edu/~tingchen/ and have been *
* converted from Matlab to C and extended to all elementary *
* patterns. *
**************************************************************/
/* 8-bits versions */
/* insprired by OpenCV's Bayer decoding */ dc1394error_t dc1394_bayer_NearestNeighbor(const uint8_t *restrict bayer, uint8_t *restrict rgb, int sx, int sy, int tile)
{
const int bayerStep = sx;
const int rgbStep = * sx;
int width = sx;
int height = sy;
int blue = tile == DC1394_COLOR_FILTER_BGGR
|| tile == DC1394_COLOR_FILTER_GBRG ? - : ;
int start_with_green = tile == DC1394_COLOR_FILTER_GBRG
|| tile == DC1394_COLOR_FILTER_GRBG;
int i, imax, iinc; if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN))
return DC1394_INVALID_COLOR_FILTER; /* add black border */
imax = sx * sy * ;
for (i = sx * (sy - ) * ; i < imax; i++)
{
rgb[i] = ;
}
iinc = (sx - ) * ;
for (i = (sx - ) * ; i < imax; i += iinc)
{
rgb[i++] = ;
rgb[i++] = ;
rgb[i++] = ;
} rgb += ;
width -= ;
height -= ; for (; height--; bayer += bayerStep, rgb += rgbStep)
{
//int t0, t1;
const uint8_t *bayerEnd = bayer + width; if (start_with_green)
{
rgb[-blue] = bayer[];
rgb[] = bayer[bayerStep + ];
rgb[blue] = bayer[bayerStep];
bayer++;
rgb += ;
} if (blue > )
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
rgb[-] = bayer[];
rgb[] = bayer[];
rgb[] = bayer[bayerStep + ]; rgb[] = bayer[];
rgb[] = bayer[bayerStep + ];
rgb[] = bayer[bayerStep + ];
}
}
else
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
rgb[] = bayer[];
rgb[] = bayer[];
rgb[-] = bayer[bayerStep + ]; rgb[] = bayer[];
rgb[] = bayer[bayerStep + ];
rgb[] = bayer[bayerStep + ];
}
} if (bayer < bayerEnd)
{
rgb[-blue] = bayer[];
rgb[] = bayer[];
rgb[blue] = bayer[bayerStep + ];
bayer++;
rgb += ;
} bayer -= width;
rgb -= width * ; blue = -blue;
start_with_green = !start_with_green;
} return DC1394_SUCCESS;
} /* OpenCV's Bayer decoding */
dc1394error_t dc1394_bayer_Bilinear(const uint8_t *restrict bayer, uint8_t *restrict rgb, int sx, int sy, int tile)
{
const int bayerStep = sx;
const int rgbStep = * sx;
int width = sx;
int height = sy;
/*
the two letters of the OpenCV name are respectively
the 4th and 3rd letters from the blinky name,
and we also have to switch R and B (OpenCV is BGR) CV_BayerBG2BGR <-> DC1394_COLOR_FILTER_BGGR
CV_BayerGB2BGR <-> DC1394_COLOR_FILTER_GBRG
CV_BayerGR2BGR <-> DC1394_COLOR_FILTER_GRBG int blue = tile == CV_BayerBG2BGR || tile == CV_BayerGB2BGR ? -1 : 1;
int start_with_green = tile == CV_BayerGB2BGR || tile == CV_BayerGR2BGR;
*/
int blue = tile == DC1394_COLOR_FILTER_BGGR
|| tile == DC1394_COLOR_FILTER_GBRG ? - : ;
int start_with_green = tile == DC1394_COLOR_FILTER_GBRG
|| tile == DC1394_COLOR_FILTER_GRBG; if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN))
return DC1394_INVALID_COLOR_FILTER; ClearBorders(rgb, sx, sy, );
rgb += rgbStep + + ;
height -= ;
width -= ; for (; height--; bayer += bayerStep, rgb += rgbStep)
{
int t0, t1;
const uint8_t *bayerEnd = bayer + width; if (start_with_green)
{
/* OpenCV has a bug in the next line, which was
t0 = (bayer[0] + bayer[bayerStep * 2] + 1) >> 1; */
t0 = (bayer[] + bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[bayerStep] + bayer[bayerStep + ] + ) >> ;
rgb[-blue] = (uint8_t) t0;
rgb[] = bayer[bayerStep + ];
rgb[blue] = (uint8_t) t1;
bayer++;
rgb += ;
} if (blue > )
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
t0 = (bayer[] + bayer[] + bayer[bayerStep * ] +
bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[] + bayer[bayerStep] +
bayer[bayerStep + ] + bayer[bayerStep * + ] +
) >> ;
rgb[-] = (uint8_t) t0;
rgb[] = (uint8_t) t1;
rgb[] = bayer[bayerStep + ]; t0 = (bayer[] + bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[bayerStep + ] + bayer[bayerStep + ] +
) >> ;
rgb[] = (uint8_t) t0;
rgb[] = bayer[bayerStep + ];
rgb[] = (uint8_t) t1;
}
}
else
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
t0 = (bayer[] + bayer[] + bayer[bayerStep * ] +
bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[] + bayer[bayerStep] +
bayer[bayerStep + ] + bayer[bayerStep * + ] +
) >> ;
rgb[] = (uint8_t) t0;
rgb[] = (uint8_t) t1;
rgb[-] = bayer[bayerStep + ]; t0 = (bayer[] + bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[bayerStep + ] + bayer[bayerStep + ] +
) >> ;
rgb[] = (uint8_t) t0;
rgb[] = bayer[bayerStep + ];
rgb[] = (uint8_t) t1;
}
} if (bayer < bayerEnd)
{
t0 = (bayer[] + bayer[] + bayer[bayerStep * ] +
bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[] + bayer[bayerStep] +
bayer[bayerStep + ] + bayer[bayerStep * + ] +
) >> ;
rgb[-blue] = (uint8_t) t0;
rgb[] = (uint8_t) t1;
rgb[blue] = bayer[bayerStep + ];
bayer++;
rgb += ;
} bayer -= width;
rgb -= width * ; blue = -blue;
start_with_green = !start_with_green;
}
return DC1394_SUCCESS;
} /* High-Quality Linear Interpolation For Demosaicing Of
Bayer-Patterned Color Images, by Henrique S. Malvar, Li-wei He, and
Ross Cutler, in ICASSP'04 */
dc1394error_t dc1394_bayer_HQLinear(const uint8_t *restrict bayer, uint8_t *restrict rgb, int sx, int sy, int tile)
{
const int bayerStep = sx;
const int rgbStep = * sx;
int width = sx;
int height = sy;
int blue = tile == DC1394_COLOR_FILTER_BGGR
|| tile == DC1394_COLOR_FILTER_GBRG ? - : ;
int start_with_green = tile == DC1394_COLOR_FILTER_GBRG
|| tile == DC1394_COLOR_FILTER_GRBG; if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN))
return DC1394_INVALID_COLOR_FILTER; ClearBorders(rgb, sx, sy, );
rgb += * rgbStep + + ;
height -= ;
width -= ; /* We begin with a (+1 line,+1 column) offset with respect to bilinear decoding, so start_with_green is the same, but blue is opposite */
blue = -blue; for (; height--; bayer += bayerStep, rgb += rgbStep)
{
int t0, t1;
const uint8_t *bayerEnd = bayer + width;
const int bayerStep2 = bayerStep * ;
const int bayerStep3 = bayerStep * ;
const int bayerStep4 = bayerStep * ; if (start_with_green)
{
/* at green pixel */
rgb[] = bayer[bayerStep2 + ];
t0 = rgb[] *
+ ((bayer[bayerStep + ] + bayer[bayerStep3 + ]) << )
- bayer[]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep4 + ]
+ ((bayer[bayerStep2] + bayer[bayerStep2 + ] + ) >> );
t1 = rgb[] * +
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ]) << )
- bayer[bayerStep2]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep2 + ]
+ ((bayer[] + bayer[bayerStep4 + ] + ) >> );
t0 = (t0 + ) >> ;
CLIP(t0, rgb[-blue]);
t1 = (t1 + ) >> ;
CLIP(t1, rgb[blue]);
bayer++;
rgb += ;
} if (blue > )
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
/* B at B */
rgb[] = bayer[bayerStep2 + ];
/* R at B */
t0 = ((bayer[bayerStep + ] + bayer[bayerStep + ] +
bayer[bayerStep3 + ] + bayer[bayerStep3 + ]) << )
-
(((bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 +
]) * + ) >> )
+ rgb[] * ;
/* G at B */
t1 = ((bayer[bayerStep + ] + bayer[bayerStep2 + ] +
bayer[bayerStep2 + ] + bayer[bayerStep3 + ]) << )
- (bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 + ])
+ (rgb[] << );
t0 = (t0 + ) >> ;
CLIP(t0, rgb[-]);
t1 = (t1 + ) >> ;
CLIP(t1, rgb[]);
/* at green pixel */
rgb[] = bayer[bayerStep2 + ];
t0 = rgb[] *
+ ((bayer[bayerStep + ] + bayer[bayerStep3 + ]) << )
- bayer[]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep4 + ]
+
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ] +
) >> );
t1 = rgb[] * +
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ]) << )
- bayer[bayerStep2 + ]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep2 + ]
+ ((bayer[] + bayer[bayerStep4 + ] + ) >> );
t0 = (t0 + ) >> ;
CLIP(t0, rgb[]);
t1 = (t1 + ) >> ;
CLIP(t1, rgb[]);
}
}
else
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
/* R at R */
rgb[-] = bayer[bayerStep2 + ];
/* B at R */
t0 = ((bayer[bayerStep + ] + bayer[bayerStep + ] +
bayer[bayerStep3 + ] + bayer[bayerStep3 + ]) << )
-
(((bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 +
]) * + ) >> )
+ rgb[-] * ;
/* G at R */
t1 = ((bayer[bayerStep + ] + bayer[bayerStep2 + ] +
bayer[bayerStep2 + ] + bayer[bayerStep * +
]) << )
- (bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 + ])
+ (rgb[-] << );
t0 = (t0 + ) >> ;
CLIP(t0, rgb[]);
t1 = (t1 + ) >> ;
CLIP(t1, rgb[]); /* at green pixel */
rgb[] = bayer[bayerStep2 + ];
t0 = rgb[] *
+ ((bayer[bayerStep + ] + bayer[bayerStep3 + ]) << )
- bayer[]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep4 + ]
+
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ] +
) >> );
t1 = rgb[] * +
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ]) << )
- bayer[bayerStep2 + ]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep2 + ]
+ ((bayer[] + bayer[bayerStep4 + ] + ) >> );
t0 = (t0 + ) >> ;
CLIP(t0, rgb[]);
t1 = (t1 + ) >> ;
CLIP(t1, rgb[]);
}
} if (bayer < bayerEnd)
{
/* B at B */
rgb[blue] = bayer[bayerStep2 + ];
/* R at B */
t0 = ((bayer[bayerStep + ] + bayer[bayerStep + ] +
bayer[bayerStep3 + ] + bayer[bayerStep3 + ]) << )
-
(((bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 +
]) * + ) >> )
+ rgb[blue] * ;
/* G at B */
t1 = (((bayer[bayerStep + ] + bayer[bayerStep2 + ] +
bayer[bayerStep2 + ] + bayer[bayerStep3 + ])) << )
- (bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 + ])
+ (rgb[blue] << );
t0 = (t0 + ) >> ;
CLIP(t0, rgb[-blue]);
t1 = (t1 + ) >> ;
CLIP(t1, rgb[]);
bayer++;
rgb += ;
} bayer -= width;
rgb -= width * ; blue = -blue;
start_with_green = !start_with_green;
} return DC1394_SUCCESS; } /* coriander's Bayer decoding */
/* Edge Sensing Interpolation II from http://www-ise.stanford.edu/~tingchen/ */
/* (Laroche,Claude A. "Apparatus and method for adaptively
interpolating a full color image utilizing chrominance gradients"
U.S. Patent 5,373,322) */
dc1394error_t dc1394_bayer_EdgeSense(const uint8_t *restrict bayer, uint8_t *restrict rgb, int sx, int sy, int tile)
{
/* Removed due to patent concerns */
return DC1394_FUNCTION_NOT_SUPPORTED;
} /* coriander's Bayer decoding */
dc1394error_t dc1394_bayer_Downsample(const uint8_t *restrict bayer, uint8_t *restrict rgb, int sx, int sy, int tile)
{
uint8_t *outR, *outG, *outB;
register int i, j;
int tmp; switch (tile)
{
case DC1394_COLOR_FILTER_GRBG:
case DC1394_COLOR_FILTER_BGGR:
outR = &rgb[];
outG = &rgb[];
outB = &rgb[];
break;
case DC1394_COLOR_FILTER_GBRG:
case DC1394_COLOR_FILTER_RGGB:
outR = &rgb[];
outG = &rgb[];
outB = &rgb[];
break;
default:
return DC1394_INVALID_COLOR_FILTER;
} switch (tile)
{
case DC1394_COLOR_FILTER_GRBG: //---------------------------------------------------------
case DC1394_COLOR_FILTER_GBRG:
for (i = ; i < sy * sx; i += (sx << ))
{
for (j = ; j < sx; j += )
{
tmp = ((bayer[i + j] + bayer[i + sx + j + ]) >> );
CLIP(tmp, outG[((i >> ) + (j >> )) * ]);
tmp = bayer[i + sx + j + ];
CLIP(tmp, outR[((i >> ) + (j >> )) * ]);
tmp = bayer[i + sx + j];
CLIP(tmp, outB[((i >> ) + (j >> )) * ]);
}
}
break;
case DC1394_COLOR_FILTER_BGGR: //---------------------------------------------------------
case DC1394_COLOR_FILTER_RGGB:
for (i = ; i < sy * sx; i += (sx << ))
{
for (j = ; j < sx; j += )
{
tmp = ((bayer[i + sx + j] + bayer[i + j + ]) >> );
CLIP(tmp, outG[((i >> ) + (j >> )) * ]);
tmp = bayer[i + sx + j + ];
CLIP(tmp, outR[((i >> ) + (j >> )) * ]);
tmp = bayer[i + j];
CLIP(tmp, outB[((i >> ) + (j >> )) * ]);
}
}
break;
} return DC1394_SUCCESS; } /* this is the method used inside AVT cameras. See AVT docs. */
dc1394error_t dc1394_bayer_Simple(const uint8_t *restrict bayer, uint8_t *restrict rgb, int sx, int sy, int tile)
{
const int bayerStep = sx;
const int rgbStep = * sx;
int width = sx;
int height = sy;
int blue = tile == DC1394_COLOR_FILTER_BGGR
|| tile == DC1394_COLOR_FILTER_GBRG ? - : ;
int start_with_green = tile == DC1394_COLOR_FILTER_GBRG
|| tile == DC1394_COLOR_FILTER_GRBG;
int i, imax, iinc; if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN))
return DC1394_INVALID_COLOR_FILTER; /* add black border */
imax = sx * sy * ;
for (i = sx * (sy - ) * ; i < imax; i++)
{
rgb[i] = ;
}
iinc = (sx - ) * ;
for (i = (sx - ) * ; i < imax; i += iinc)
{
rgb[i++] = ;
rgb[i++] = ;
rgb[i++] = ;
} rgb += ;
width -= ;
height -= ; for (; height--; bayer += bayerStep, rgb += rgbStep)
{
const uint8_t *bayerEnd = bayer + width; if (start_with_green)
{
rgb[-blue] = bayer[];
rgb[] = (bayer[] + bayer[bayerStep + ] + ) >> ;
rgb[blue] = bayer[bayerStep];
bayer++;
rgb += ;
} if (blue > )
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
rgb[-] = bayer[];
rgb[] = (bayer[] + bayer[bayerStep] + ) >> ;
rgb[] = bayer[bayerStep + ]; rgb[] = bayer[];
rgb[] = (bayer[] + bayer[bayerStep + ] + ) >> ;
rgb[] = bayer[bayerStep + ];
}
}
else
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
rgb[] = bayer[];
rgb[] = (bayer[] + bayer[bayerStep] + ) >> ;
rgb[-] = bayer[bayerStep + ]; rgb[] = bayer[];
rgb[] = (bayer[] + bayer[bayerStep + ] + ) >> ;
rgb[] = bayer[bayerStep + ];
}
} if (bayer < bayerEnd)
{
rgb[-blue] = bayer[];
rgb[] = (bayer[] + bayer[bayerStep] + ) >> ;
rgb[blue] = bayer[bayerStep + ];
bayer++;
rgb += ;
} bayer -= width;
rgb -= width * ; blue = -blue;
start_with_green = !start_with_green;
} return DC1394_SUCCESS; } /* 16-bits versions */ /* insprired by OpenCV's Bayer decoding */
dc1394error_t dc1394_bayer_NearestNeighbor_uint16(const uint16_t *restrict bayer, uint16_t *restrict rgb, int sx, int sy, int tile, int bits)
{
const int bayerStep = sx;
const int rgbStep = * sx;
int width = sx;
int height = sy;
int blue = tile == DC1394_COLOR_FILTER_BGGR
|| tile == DC1394_COLOR_FILTER_GBRG ? - : ;
int start_with_green = tile == DC1394_COLOR_FILTER_GBRG
|| tile == DC1394_COLOR_FILTER_GRBG;
int i, iinc, imax; if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN))
return DC1394_INVALID_COLOR_FILTER; /* add black border */
imax = sx * sy * ;
for (i = sx * (sy - ) * ; i < imax; i++)
{
rgb[i] = ;
}
iinc = (sx - ) * ;
for (i = (sx - ) * ; i < imax; i += iinc)
{
rgb[i++] = ;
rgb[i++] = ;
rgb[i++] = ;
} rgb += ;
height -= ;
width -= ; for (; height--; bayer += bayerStep, rgb += rgbStep)
{
//int t0, t1;
const uint16_t *bayerEnd = bayer + width; if (start_with_green)
{
rgb[-blue] = bayer[];
rgb[] = bayer[bayerStep + ];
rgb[blue] = bayer[bayerStep];
bayer++;
rgb += ;
} if (blue > )
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
rgb[-] = bayer[];
rgb[] = bayer[];
rgb[] = bayer[bayerStep + ]; rgb[] = bayer[];
rgb[] = bayer[bayerStep + ];
rgb[] = bayer[bayerStep + ];
}
}
else
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
rgb[] = bayer[];
rgb[] = bayer[];
rgb[-] = bayer[bayerStep + ]; rgb[] = bayer[];
rgb[] = bayer[bayerStep + ];
rgb[] = bayer[bayerStep + ];
}
} if (bayer < bayerEnd)
{
rgb[-blue] = bayer[];
rgb[] = bayer[];
rgb[blue] = bayer[bayerStep + ];
bayer++;
rgb += ;
} bayer -= width;
rgb -= width * ; blue = -blue;
start_with_green = !start_with_green;
} return DC1394_SUCCESS; }
/* OpenCV's Bayer decoding */
dc1394error_t dc1394_bayer_Bilinear_uint16(const uint16_t *restrict bayer, uint16_t *restrict rgb, int sx, int sy, int tile, int bits)
{
const int bayerStep = sx;
const int rgbStep = * sx;
int width = sx;
int height = sy;
int blue = tile == DC1394_COLOR_FILTER_BGGR
|| tile == DC1394_COLOR_FILTER_GBRG ? - : ;
int start_with_green = tile == DC1394_COLOR_FILTER_GBRG
|| tile == DC1394_COLOR_FILTER_GRBG; if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN))
return DC1394_INVALID_COLOR_FILTER; rgb += rgbStep + + ;
height -= ;
width -= ; for (; height--; bayer += bayerStep, rgb += rgbStep)
{
int t0, t1;
const uint16_t *bayerEnd = bayer + width; if (start_with_green)
{
/* OpenCV has a bug in the next line, which was
t0 = (bayer[0] + bayer[bayerStep * 2] + 1) >> 1; */
t0 = (bayer[] + bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[bayerStep] + bayer[bayerStep + ] + ) >> ;
rgb[-blue] = (uint16_t) t0;
rgb[] = bayer[bayerStep + ];
rgb[blue] = (uint16_t) t1;
bayer++;
rgb += ;
} if (blue > )
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
t0 = (bayer[] + bayer[] + bayer[bayerStep * ] +
bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[] + bayer[bayerStep] +
bayer[bayerStep + ] + bayer[bayerStep * + ] +
) >> ;
rgb[-] = (uint16_t) t0;
rgb[] = (uint16_t) t1;
rgb[] = bayer[bayerStep + ]; t0 = (bayer[] + bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[bayerStep + ] + bayer[bayerStep + ] +
) >> ;
rgb[] = (uint16_t) t0;
rgb[] = bayer[bayerStep + ];
rgb[] = (uint16_t) t1;
}
}
else
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
t0 = (bayer[] + bayer[] + bayer[bayerStep * ] +
bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[] + bayer[bayerStep] +
bayer[bayerStep + ] + bayer[bayerStep * + ] +
) >> ;
rgb[] = (uint16_t) t0;
rgb[] = (uint16_t) t1;
rgb[-] = bayer[bayerStep + ]; t0 = (bayer[] + bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[bayerStep + ] + bayer[bayerStep + ] +
) >> ;
rgb[] = (uint16_t) t0;
rgb[] = bayer[bayerStep + ];
rgb[] = (uint16_t) t1;
}
} if (bayer < bayerEnd)
{
t0 = (bayer[] + bayer[] + bayer[bayerStep * ] +
bayer[bayerStep * + ] + ) >> ;
t1 = (bayer[] + bayer[bayerStep] +
bayer[bayerStep + ] + bayer[bayerStep * + ] +
) >> ;
rgb[-blue] = (uint16_t) t0;
rgb[] = (uint16_t) t1;
rgb[blue] = bayer[bayerStep + ];
bayer++;
rgb += ;
} bayer -= width;
rgb -= width * ; blue = -blue;
start_with_green = !start_with_green;
} return DC1394_SUCCESS; } /* High-Quality Linear Interpolation For Demosaicing Of
Bayer-Patterned Color Images, by Henrique S. Malvar, Li-wei He, and
Ross Cutler, in ICASSP'04 */
dc1394error_t dc1394_bayer_HQLinear_uint16(const uint16_t *restrict bayer, uint16_t *restrict rgb, int sx, int sy, int tile, int bits)
{
const int bayerStep = sx;
const int rgbStep = * sx;
int width = sx;
int height = sy;
/*
the two letters of the OpenCV name are respectively
the 4th and 3rd letters from the blinky name,
and we also have to switch R and B (OpenCV is BGR) CV_BayerBG2BGR <-> DC1394_COLOR_FILTER_BGGR
CV_BayerGB2BGR <-> DC1394_COLOR_FILTER_GBRG
CV_BayerGR2BGR <-> DC1394_COLOR_FILTER_GRBG int blue = tile == CV_BayerBG2BGR || tile == CV_BayerGB2BGR ? -1 : 1;
int start_with_green = tile == CV_BayerGB2BGR || tile == CV_BayerGR2BGR;
*/
int blue = tile == DC1394_COLOR_FILTER_BGGR
|| tile == DC1394_COLOR_FILTER_GBRG ? - : ;
int start_with_green = tile == DC1394_COLOR_FILTER_GBRG
|| tile == DC1394_COLOR_FILTER_GRBG; if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN))
return DC1394_INVALID_COLOR_FILTER; ClearBorders_uint16(rgb, sx, sy, );
rgb += * rgbStep + + ;
height -= ;
width -= ; /* We begin with a (+1 line,+1 column) offset with respect to bilinear decoding, so start_with_green is the same, but blue is opposite */
blue = -blue; for (; height--; bayer += bayerStep, rgb += rgbStep)
{
int t0, t1;
const uint16_t *bayerEnd = bayer + width;
const int bayerStep2 = bayerStep * ;
const int bayerStep3 = bayerStep * ;
const int bayerStep4 = bayerStep * ; if (start_with_green)
{
/* at green pixel */
rgb[] = bayer[bayerStep2 + ];
t0 = rgb[] *
+ ((bayer[bayerStep + ] + bayer[bayerStep3 + ]) << )
- bayer[]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep4 + ]
+ ((bayer[bayerStep2] + bayer[bayerStep2 + ] + ) >> );
t1 = rgb[] * +
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ]) << )
- bayer[bayerStep2]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep2 + ]
+ ((bayer[] + bayer[bayerStep4 + ] + ) >> );
t0 = (t0 + ) >> ;
CLIP16(t0, rgb[-blue], bits);
t1 = (t1 + ) >> ;
CLIP16(t1, rgb[blue], bits);
bayer++;
rgb += ;
} if (blue > )
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
/* B at B */
rgb[] = bayer[bayerStep2 + ];
/* R at B */
t0 = ((bayer[bayerStep + ] + bayer[bayerStep + ] +
bayer[bayerStep3 + ] + bayer[bayerStep3 + ]) << )
-
(((bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 +
]) * + ) >> )
+ rgb[] * ;
/* G at B */
t1 = ((bayer[bayerStep + ] + bayer[bayerStep2 + ] +
bayer[bayerStep2 + ] + bayer[bayerStep * +
]) << )
- (bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 + ])
+ (rgb[] << );
t0 = (t0 + ) >> ;
CLIP16(t0, rgb[-], bits);
t1 = (t1 + ) >> ;
CLIP16(t1, rgb[], bits);
/* at green pixel */
rgb[] = bayer[bayerStep2 + ];
t0 = rgb[] *
+ ((bayer[bayerStep + ] + bayer[bayerStep3 + ]) << )
- bayer[]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep4 + ]
+
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ] +
) >> );
t1 = rgb[] * +
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ]) << )
- bayer[bayerStep2 + ]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep2 + ]
+ ((bayer[] + bayer[bayerStep4 + ] + ) >> );
t0 = (t0 + ) >> ;
CLIP16(t0, rgb[], bits);
t1 = (t1 + ) >> ;
CLIP16(t1, rgb[], bits);
}
}
else
{
for (; bayer <= bayerEnd - ; bayer += , rgb += )
{
/* R at R */
rgb[-] = bayer[bayerStep2 + ];
/* B at R */
t0 = ((bayer[bayerStep + ] + bayer[bayerStep + ] +
bayer[bayerStep * + ] + bayer[bayerStep3 +
]) << )
-
(((bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 +
]) * + ) >> )
+ rgb[-] * ;
/* G at R */
t1 = ((bayer[bayerStep + ] + bayer[bayerStep2 + ] +
bayer[bayerStep2 + ] + bayer[bayerStep3 + ]) << )
- (bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 + ])
+ (rgb[-] << );
t0 = (t0 + ) >> ;
CLIP16(t0, rgb[], bits);
t1 = (t1 + ) >> ;
CLIP16(t1, rgb[], bits); /* at green pixel */
rgb[] = bayer[bayerStep2 + ];
t0 = rgb[] *
+ ((bayer[bayerStep + ] + bayer[bayerStep3 + ]) << )
- bayer[]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep4 + ]
+
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ] +
) >> );
t1 = rgb[] * +
((bayer[bayerStep2 + ] + bayer[bayerStep2 + ]) << )
- bayer[bayerStep2 + ]
- bayer[bayerStep + ]
- bayer[bayerStep + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep3 + ]
- bayer[bayerStep2 + ]
+ ((bayer[] + bayer[bayerStep4 + ] + ) >> );
t0 = (t0 + ) >> ;
CLIP16(t0, rgb[], bits);
t1 = (t1 + ) >> ;
CLIP16(t1, rgb[], bits);
}
} if (bayer < bayerEnd)
{
/* B at B */
rgb[blue] = bayer[bayerStep2 + ];
/* R at B */
t0 = ((bayer[bayerStep + ] + bayer[bayerStep + ] +
bayer[bayerStep3 + ] + bayer[bayerStep3 + ]) << )
-
(((bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 +
]) * + ) >> )
+ rgb[blue] * ;
/* G at B */
t1 = (((bayer[bayerStep + ] + bayer[bayerStep2 + ] +
bayer[bayerStep2 + ] + bayer[bayerStep3 + ])) << )
- (bayer[] + bayer[bayerStep2] +
bayer[bayerStep2 + ] + bayer[bayerStep4 + ])
+ (rgb[blue] << );
t0 = (t0 + ) >> ;
CLIP16(t0, rgb[-blue], bits);
t1 = (t1 + ) >> ;
CLIP16(t1, rgb[], bits);
bayer++;
rgb += ;
} bayer -= width;
rgb -= width * ; blue = -blue;
start_with_green = !start_with_green;
} return DC1394_SUCCESS;
} /* coriander's Bayer decoding */
dc1394error_t dc1394_bayer_EdgeSense_uint16(const uint16_t *restrict bayer, uint16_t *restrict rgb, int sx, int sy, int tile, int bits)
{
/* Removed due to patent concerns */
return DC1394_FUNCTION_NOT_SUPPORTED;
} /* coriander's Bayer decoding */
dc1394error_t dc1394_bayer_Downsample_uint16(const uint16_t *restrict bayer, uint16_t *restrict rgb, int sx, int sy, int tile, int bits)
{
uint16_t *outR, *outG, *outB;
register int i, j;
int tmp; switch (tile)
{
case DC1394_COLOR_FILTER_GRBG:
case DC1394_COLOR_FILTER_BGGR:
outR = &rgb[];
outG = &rgb[];
outB = &rgb[];
break;
case DC1394_COLOR_FILTER_GBRG:
case DC1394_COLOR_FILTER_RGGB:
outR = &rgb[];
outG = &rgb[];
outB = &rgb[];
break;
default:
return DC1394_INVALID_COLOR_FILTER;
} switch (tile)
{
case DC1394_COLOR_FILTER_GRBG: //---------------------------------------------------------
case DC1394_COLOR_FILTER_GBRG:
for (i = ; i < sy * sx; i += (sx << ))
{
for (j = ; j < sx; j += )
{
tmp =
((bayer[i + j] + bayer[i + sx + j + ]) >> );
CLIP16(tmp, outG[((i >> ) + (j >> )) * ], bits);
tmp = bayer[i + sx + j + ];
CLIP16(tmp, outR[((i >> ) + (j >> )) * ], bits);
tmp = bayer[i + sx + j];
CLIP16(tmp, outB[((i >> ) + (j >> )) * ], bits);
}
}
break;
case DC1394_COLOR_FILTER_BGGR: //---------------------------------------------------------
case DC1394_COLOR_FILTER_RGGB:
for (i = ; i < sy * sx; i += (sx << ))
{
for (j = ; j < sx; j += )
{
tmp =
((bayer[i + sx + j] + bayer[i + j + ]) >> );
CLIP16(tmp, outG[((i >> ) + (j >> )) * ], bits);
tmp = bayer[i + sx + j + ];
CLIP16(tmp, outR[((i >> ) + (j >> )) * ], bits);
tmp = bayer[i + j];
CLIP16(tmp, outB[((i >> ) + (j >> )) * ], bits);
}
}
break;
} return DC1394_SUCCESS; } /* coriander's Bayer decoding */
dc1394error_t dc1394_bayer_Simple_uint16(const uint16_t *restrict bayer, uint16_t *restrict rgb, int sx, int sy, int tile, int bits)
{
uint16_t *outR, *outG, *outB;
register int i, j;
int tmp, base; // sx and sy should be even
switch (tile)
{
case DC1394_COLOR_FILTER_GRBG:
case DC1394_COLOR_FILTER_BGGR:
outR = &rgb[];
outG = &rgb[];
outB = &rgb[];
break;
case DC1394_COLOR_FILTER_GBRG:
case DC1394_COLOR_FILTER_RGGB:
outR = &rgb[];
outG = &rgb[];
outB = &rgb[];
break;
default:
return DC1394_INVALID_COLOR_FILTER;
} switch (tile)
{
case DC1394_COLOR_FILTER_GRBG:
case DC1394_COLOR_FILTER_BGGR:
outR = &rgb[];
outG = &rgb[];
outB = &rgb[];
break;
case DC1394_COLOR_FILTER_GBRG:
case DC1394_COLOR_FILTER_RGGB:
outR = &rgb[];
outG = &rgb[];
outB = &rgb[];
break;
default:
outR = NULL;
outG = NULL;
outB = NULL;
break;
} switch (tile)
{
case DC1394_COLOR_FILTER_GRBG: //---------------------------------------------------------
case DC1394_COLOR_FILTER_GBRG:
for (i = ; i < sy - ; i += )
{
for (j = ; j < sx - ; j += )
{
base = i * sx + j;
tmp = ((bayer[base] + bayer[base + sx + ]) >> );
CLIP16(tmp, outG[base * ], bits);
tmp = bayer[base + ];
CLIP16(tmp, outR[base * ], bits);
tmp = bayer[base + sx];
CLIP16(tmp, outB[base * ], bits);
}
}
for (i = ; i < sy - ; i += )
{
for (j = ; j < sx - ; j += )
{
base = i * sx + j;
tmp = ((bayer[base + ] + bayer[base + sx]) >> );
CLIP16(tmp, outG[(base) * ], bits);
tmp = bayer[base];
CLIP16(tmp, outR[(base) * ], bits);
tmp = bayer[base + + sx];
CLIP16(tmp, outB[(base) * ], bits);
}
}
for (i = ; i < sy - ; i += )
{
for (j = ; j < sx - ; j += )
{
base = i * sx + j;
tmp = ((bayer[base + sx] + bayer[base + ]) >> );
CLIP16(tmp, outG[base * ], bits);
tmp = bayer[base + sx + ];
CLIP16(tmp, outR[base * ], bits);
tmp = bayer[base];
CLIP16(tmp, outB[base * ], bits);
}
}
for (i = ; i < sy - ; i += )
{
for (j = ; j < sx - ; j += )
{
base = i * sx + j;
tmp = ((bayer[base] + bayer[base + + sx]) >> );
CLIP16(tmp, outG[(base) * ], bits);
tmp = bayer[base + sx];
CLIP16(tmp, outR[(base) * ], bits);
tmp = bayer[base + ];
CLIP16(tmp, outB[(base) * ], bits);
}
}
break;
case DC1394_COLOR_FILTER_BGGR: //---------------------------------------------------------
case DC1394_COLOR_FILTER_RGGB:
for (i = ; i < sy - ; i += )
{
for (j = ; j < sx - ; j += )
{
base = i * sx + j;
tmp = ((bayer[base + sx] + bayer[base + ]) >> );
CLIP16(tmp, outG[base * ], bits);
tmp = bayer[base + sx + ];
CLIP16(tmp, outR[base * ], bits);
tmp = bayer[base];
CLIP16(tmp, outB[base * ], bits);
}
}
for (i = ; i < sy - ; i += )
{
for (j = ; j < sx - ; j += )
{
base = i * sx + j;
tmp = ((bayer[base] + bayer[base + + sx]) >> );
CLIP16(tmp, outG[(base) * ], bits);
tmp = bayer[base + ];
CLIP16(tmp, outR[(base) * ], bits);
tmp = bayer[base + sx];
CLIP16(tmp, outB[(base) * ], bits);
}
}
for (i = ; i < sy - ; i += )
{
for (j = ; j < sx - ; j += )
{
base = i * sx + j;
tmp = ((bayer[base] + bayer[base + sx + ]) >> );
CLIP16(tmp, outG[base * ], bits);
tmp = bayer[base + sx];
CLIP16(tmp, outR[base * ], bits);
tmp = bayer[base + ];
CLIP16(tmp, outB[base * ], bits);
}
}
for (i = ; i < sy - ; i += )
{
for (j = ; j < sx - ; j += )
{
base = i * sx + j;
tmp = ((bayer[base + ] + bayer[base + sx]) >> );
CLIP16(tmp, outG[(base) * ], bits);
tmp = bayer[base];
CLIP16(tmp, outR[(base) * ], bits);
tmp = bayer[base + + sx];
CLIP16(tmp, outB[(base) * ], bits);
}
}
break;
} /* add black border */
for (i = sx * (sy - ) * ; i < sx * sy * ; i++)
{
rgb[i] = ;
}
for (i = (sx - ) * ; i < sx * sy * ; i += (sx - ) * )
{
rgb[i++] = ;
rgb[i++] = ;
rgb[i++] = ;
} return DC1394_SUCCESS; } /* Variable Number of Gradients, from dcraw <http://www.cybercom.net/~dcoffin/dcraw/> */
/* Ported to libdc1394 by Frederic Devernay */ #define FORC3 for (c=0; c < 3; c++) #define SQR(x) ((x)*(x))
#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#define LIM(x,min,max) MAX(min,MIN(x,max))
#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
/*
In order to inline this calculation, I make the risky
assumption that all filter patterns can be described
by a repeating pattern of eight rows and two columns Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
*/
#define FC(row,col) \
(filters >> ((((row) << & ) + ((col) & )) << ) & ) /*
This algorithm is officially called: "Interpolation using a Threshold-based variable number of gradients" described in http://www-ise.stanford.edu/~tingchen/algodep/vargra.html I've extended the basic idea to work with non-Bayer filter arrays.
Gradients are numbered clockwise from NW=0 to W=7.
*/
static const signed char bayervng_terms[] =
{
-, -, +, -, , 0x01, -, -, +, +, , 0x01, -, -, -, +, , 0x01,
-, -, +, -, , 0x02, -, -, +, +, , 0x03, -, -, +, +, , 0x01,
-, +, +, -, , 0x06, -, +, +, +, , 0x02, -, +, +, +, , 0x03,
-, +, -, +, , 0x04, -, +, +, -, , 0x04, -, +, +, +, , 0x06,
-, +, +, +, , 0x02, -, +, +, +, , 0x04, -, +, +, +, , 0x04,
-, -, -, +, , 0x80, -, -, +, -, , 0x01, -, -, +, -, , 0x01,
-, -, +, +, , 0x01, -, -, -, +, , 0x88, -, -, +, -, , 0x40,
-, -, +, -, , 0x22, -, -, +, +, , 0x33, -, -, +, +, , 0x11,
-, +, -, +, , 0x08, -, +, +, -, , 0x44, -, +, +, +, , 0x11,
-, +, +, -, , 0x40, -, +, +, -, , 0x66, -, +, +, +, , 0x22,
-, +, +, +, , 0x33, -, +, +, +, , 0x10, -, +, +, -, , 0x44,
-, +, +, +, , 0x66, -, +, +, +, , 0x22, -, +, +, +, , 0x10,
-, +, +, +, , 0x04, -, +, +, +, , 0x04, -, +, +, +, , 0x04,
+, -, +, +, , 0x80, +, -, +, +, , 0x88, +, -, +, -, , 0x40,
+, -, +, +, , 0x11, +, -, +, -, , 0x40, +, -, +, -, , 0x20,
+, -, +, +, , 0x30, +, -, +, +, , 0x10, +, +, +, +, , 0x08,
+, +, +, -, , 0x40, +, +, +, -, , 0x60, +, +, +, +, , 0x20,
+, +, +, +, , 0x30, +, +, +, +, , 0x10, +, +, +, +, , 0x44,
+, +, +, +, , 0x10, +, +, +, -, , 0x40, +, +, +, +, , 0x60,
+, +, +, +, , 0x20, +, +, +, +, , 0x10, +, -, +, +, , 0x80,
+, -, +, +, , 0x88, +, +, +, +, , 0x08, +, +, +, -, , 0x40,
+, +, +, +, , 0x10
}, bayervng_chood[] = { -, -, -, , -, +, , +, +, +, +, , +, -, , - }; dc1394error_t dc1394_bayer_VNG(const uint8_t *restrict bayer, uint8_t *restrict dst, int sx, int sy, dc1394color_filter_t pattern)
{
const int height = sy, width = sx;
static const signed char *cp;
/* the following has the same type as the image */
uint8_t (*brow[])[], *pix; /* [FD] */
int code[][][], *ip, gval[], gmin, gmax, sum[];
int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
int g, diff, thold, num, c;
uint32_t filters; /* [FD] */ /* first, use bilinear bayer decoding */
dc1394_bayer_Bilinear(bayer, dst, sx, sy, pattern); switch(pattern)
{
case DC1394_COLOR_FILTER_BGGR:
filters = 0x16161616;
break;
case DC1394_COLOR_FILTER_GRBG:
filters = 0x61616161;
break;
case DC1394_COLOR_FILTER_RGGB:
filters = 0x94949494;
break;
case DC1394_COLOR_FILTER_GBRG:
filters = 0x49494949;
break;
default:
return DC1394_INVALID_COLOR_FILTER;
} for (row = ; row < ; row++) /* Precalculate for VNG */
{
for (col = ; col < ; col++)
{
ip = code[row][col];
for (cp = bayervng_terms, t = ; t < ; t++)
{
y1 = *cp++;
x1 = *cp++;
y2 = *cp++;
x2 = *cp++;
weight = *cp++;
grads = *cp++;
color = FC(row + y1, col + x1);
if (FC(row + y2, col + x2) != color) continue;
diag = (FC(row, col + ) == color && FC(row + , col) == color) ? : ;
if (abs(y1 - y2) == diag && abs(x1 - x2) == diag) continue;
*ip++ = (y1 * width + x1) * + color; /* [FD] */
*ip++ = (y2 * width + x2) * + color; /* [FD] */
*ip++ = weight;
for (g = ; g < ; g++)
if (grads & << g) *ip++ = g;
*ip++ = -;
}
*ip++ = INT_MAX;
for (cp = bayervng_chood, g = ; g < ; g++)
{
y = *cp++;
x = *cp++;
*ip++ = (y * width + x) * ; /* [FD] */
color = FC(row, col);
if (FC(row + y, col + x) != color && FC(row + y * , col + x * ) == color)
*ip++ = (y * width + x) * + color; /* [FD] */
else
*ip++ = ;
}
}
}
brow[] = calloc (width * , sizeof **brow);
//merror (brow[4], "vng_interpolate()");
for (row = ; row < ; row++)
brow[row] = brow[] + row * width;
for (row = ; row < height - ; row++) /* Do VNG interpolation */
{
for (col = ; col < width - ; col++)
{
pix = dst + (row * width + col) * ; /* [FD] */
ip = code[row & ][col & ];
memset (gval, , sizeof gval);
while ((g = ip[]) != INT_MAX) /* Calculate gradients */
{
diff = ABS(pix[g] - pix[ip[]]) << ip[];
gval[ip[]] += diff;
ip += ;
if ((g = ip[-]) == -) continue;
gval[g] += diff;
while ((g = *ip++) != -)
gval[g] += diff;
}
ip++;
gmin = gmax = gval[]; /* Choose a threshold */
for (g = ; g < ; g++)
{
if (gmin > gval[g]) gmin = gval[g];
if (gmax < gval[g]) gmax = gval[g];
}
if (gmax == )
{
memcpy (brow[][col], pix, * sizeof * dst); /* [FD] */
continue;
}
thold = gmin + (gmax >> );
memset (sum, , sizeof sum);
color = FC(row, col);
for (num = g = ; g < ; g++, ip += ) /* Average the neighbors */
{
if (gval[g] <= thold)
{
for (c = ; c < ; c++) /* [FD] */
if (c == color && ip[])
sum[c] += (pix[c] + pix[ip[]]) >> ;
else
sum[c] += pix[ip[] + c];
num++;
}
}
for (c = ; c < ; c++) /* [FD] Save to buffer */
{
t = pix[color];
if (c != color)
t += (sum[c] - sum[color]) / num;
CLIP(t, brow[][col][c]); /* [FD] */
}
}
if (row > ) /* Write buffer to image */
memcpy (dst + * ((row - )*width + ), brow[] + , (width - ) * * sizeof * dst); /* [FD] */
for (g = ; g < ; g++)
brow[(g-) & ] = brow[g];
}
memcpy (dst + * ((row - )*width + ), brow[] + , (width - ) * * sizeof * dst);
memcpy (dst + * ((row - )*width + ), brow[] + , (width - ) * * sizeof * dst);
free (brow[]); return DC1394_SUCCESS;
} dc1394error_t dc1394_bayer_VNG_uint16(const uint16_t *restrict bayer, uint16_t *restrict dst, int sx, int sy, dc1394color_filter_t pattern, int bits)
{
const int height = sy, width = sx;
static const signed char *cp;
/* the following has the same type as the image */
uint16_t (*brow[])[], *pix; /* [FD] */
int code[][][], *ip, gval[], gmin, gmax, sum[];
int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
int g, diff, thold, num, c;
uint32_t filters; /* [FD] */ /* first, use bilinear bayer decoding */ dc1394_bayer_Bilinear_uint16(bayer, dst, sx, sy, pattern, bits); switch(pattern)
{
case DC1394_COLOR_FILTER_BGGR:
filters = 0x16161616;
break;
case DC1394_COLOR_FILTER_GRBG:
filters = 0x61616161;
break;
case DC1394_COLOR_FILTER_RGGB:
filters = 0x94949494;
break;
case DC1394_COLOR_FILTER_GBRG:
filters = 0x49494949;
break;
default:
return DC1394_INVALID_COLOR_FILTER;
} for (row = ; row < ; row++) /* Precalculate for VNG */
{
for (col = ; col < ; col++)
{
ip = code[row][col];
for (cp = bayervng_terms, t = ; t < ; t++)
{
y1 = *cp++;
x1 = *cp++;
y2 = *cp++;
x2 = *cp++;
weight = *cp++;
grads = *cp++;
color = FC(row + y1, col + x1);
if (FC(row + y2, col + x2) != color) continue;
diag = (FC(row, col + ) == color && FC(row + , col) == color) ? : ;
if (abs(y1 - y2) == diag && abs(x1 - x2) == diag) continue;
*ip++ = (y1 * width + x1) * + color; /* [FD] */
*ip++ = (y2 * width + x2) * + color; /* [FD] */
*ip++ = weight;
for (g = ; g < ; g++)
if (grads & << g) *ip++ = g;
*ip++ = -;
}
*ip++ = INT_MAX;
for (cp = bayervng_chood, g = ; g < ; g++)
{
y = *cp++;
x = *cp++;
*ip++ = (y * width + x) * ; /* [FD] */
color = FC(row, col);
if (FC(row + y, col + x) != color && FC(row + y * , col + x * ) == color)
*ip++ = (y * width + x) * + color; /* [FD] */
else
*ip++ = ;
}
}
}
brow[] = calloc (width * , sizeof **brow);
//merror (brow[4], "vng_interpolate()");
for (row = ; row < ; row++)
brow[row] = brow[] + row * width;
for (row = ; row < height - ; row++) /* Do VNG interpolation */
{
for (col = ; col < width - ; col++)
{
pix = dst + (row * width + col) * ; /* [FD] */
ip = code[row & ][col & ];
memset (gval, , sizeof gval);
while ((g = ip[]) != INT_MAX) /* Calculate gradients */
{
diff = ABS(pix[g] - pix[ip[]]) << ip[];
gval[ip[]] += diff;
ip += ;
if ((g = ip[-]) == -) continue;
gval[g] += diff;
while ((g = *ip++) != -)
gval[g] += diff;
}
ip++;
gmin = gmax = gval[]; /* Choose a threshold */
for (g = ; g < ; g++)
{
if (gmin > gval[g]) gmin = gval[g];
if (gmax < gval[g]) gmax = gval[g];
}
if (gmax == )
{
memcpy (brow[][col], pix, * sizeof * dst); /* [FD] */
continue;
}
thold = gmin + (gmax >> );
memset (sum, , sizeof sum);
color = FC(row, col);
for (num = g = ; g < ; g++, ip += ) /* Average the neighbors */
{
if (gval[g] <= thold)
{
for (c = ; c < ; c++) /* [FD] */
if (c == color && ip[])
sum[c] += (pix[c] + pix[ip[]]) >> ;
else
sum[c] += pix[ip[] + c];
num++;
}
}
for (c = ; c < ; c++) /* [FD] Save to buffer */
{
t = pix[color];
if (c != color)
t += (sum[c] - sum[color]) / num;
CLIP16(t, brow[][col][c], bits); /* [FD] */
}
}
if (row > ) /* Write buffer to image */
memcpy (dst + * ((row - )*width + ), brow[] + , (width - ) * * sizeof * dst); /* [FD] */
for (g = ; g < ; g++)
brow[(g-) & ] = brow[g];
}
memcpy (dst + * ((row - )*width + ), brow[] + , (width - ) * * sizeof * dst);
memcpy (dst + * ((row - )*width + ), brow[] + , (width - ) * * sizeof * dst);
free (brow[]); return DC1394_SUCCESS;
} /* AHD interpolation ported from dcraw to libdc1394 by Samuel Audet */
static dc1394bool_t ahd_inited = DC1394_FALSE; /* WARNING: not multi-processor safe */ #define CLIPOUT(x) LIM(x,0,255)
#define CLIPOUT16(x,bits) LIM(x,0,((1<<bits)-1)) static const double xyz_rgb[][] = /* XYZ from RGB */
{
{ 0.412453, 0.357580, 0.180423 },
{ 0.212671, 0.715160, 0.072169 },
{ 0.019334, 0.119193, 0.950227 }
};
static const float d65_white[] = { 0.950456, , 1.088754 }; static void cam_to_cielab (uint16_t cam[], float lab[]) /* [SA] */
{
int c, i, j;
float r, xyz[];
static float cbrt[0x10000], xyz_cam[][]; if (cam == NULL)
{
for (i = ; i < 0x10000; i++)
{
r = i / 65535.0;
cbrt[i] = r > 0.008856 ? pow(r, / 3.0) : 7.787 * r + / 116.0;
}
for (i = ; i < ; i++)
for (j = ; j < ; j++) /* [SA] */
xyz_cam[i][j] = xyz_rgb[i][j] / d65_white[i]; /* [SA] */
}
else
{
xyz[] = xyz[] = xyz[] = 0.5;
FORC3 /* [SA] */
{
xyz[] += xyz_cam[][c] * cam[c];
xyz[] += xyz_cam[][c] * cam[c];
xyz[] += xyz_cam[][c] * cam[c];
}
xyz[] = cbrt[CLIPOUT16((int) xyz[], )]; /* [SA] */
xyz[] = cbrt[CLIPOUT16((int) xyz[], )]; /* [SA] */
xyz[] = cbrt[CLIPOUT16((int) xyz[], )]; /* [SA] */
lab[] = * xyz[] - ;
lab[] = * (xyz[] - xyz[]);
lab[] = * (xyz[] - xyz[]);
}
} /*
Adaptive Homogeneity-Directed interpolation is based on
the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
*/
#define TS 256 /* Tile Size */ dc1394error_t dc1394_bayer_AHD(const uint8_t *restrict bayer, uint8_t *restrict dst, int sx, int sy, dc1394color_filter_t pattern)
{
int i, j, top, left, row, col, tr, tc, fc, c, d, val, hm[];
/* the following has the same type as the image */
uint8_t (*pix)[], (*rix)[]; /* [SA] */
uint16_t rix16[]; /* [SA] */
static const int dir[] = { -, , -TS, TS };
unsigned ldiff[][], abdiff[][], leps, abeps;
float flab[]; /* [SA] */
uint8_t (*rgb)[TS][TS][];
short (*lab)[TS][TS][];
char (*homo)[TS][TS], *buffer; /* start - new code for libdc1394 */
uint32_t filters;
const int height = sy, width = sx;
int x, y; if (ahd_inited == DC1394_FALSE)
{
/* WARNING: this might not be multi-processor safe */
cam_to_cielab (NULL, NULL);
ahd_inited = DC1394_TRUE;
} switch(pattern)
{
case DC1394_COLOR_FILTER_BGGR:
filters = 0x16161616;
break;
case DC1394_COLOR_FILTER_GRBG:
filters = 0x61616161;
break;
case DC1394_COLOR_FILTER_RGGB:
filters = 0x94949494;
break;
case DC1394_COLOR_FILTER_GBRG:
filters = 0x49494949;
break;
default:
return DC1394_INVALID_COLOR_FILTER;
} /* fill-in destination with known exact values */
for (y = ; y < height; y++)
{
for (x = ; x < width; x++)
{
int channel = FC(y, x);
dst[(y*width+x)* + channel] = bayer[y*width+x];
}
}
/* end - new code for libdc1394 */ /* start - code from border_interpolate (int border) */
{
int border = ;
unsigned row, col, y, x, f, c, sum[]; for (row = ; row < height; row++)
for (col = ; col < width; col++)
{
if (col == border && row >= border && row < height - border)
col = width - border;
memset (sum, , sizeof sum);
for (y = row - ; y != row + ; y++)
for (x = col - ; x != col + ; x++)
if (y < height && x < width)
{
f = FC(y, x);
sum[f] += dst[(y*width+x)* + f]; /* [SA] */
sum[f+]++;
}
f = FC(row, col);
FORC3 if (c != f && sum[c+]) /* [SA] */
dst[(row*width+col)* + c] = sum[c] / sum[c+]; /* [SA] */
}
}
/* end - code from border_interpolate (int border) */ buffer = (char *) malloc ( * TS * TS); /* 1664 kB */
/* merror (buffer, "ahd_interpolate()"); */
rgb = (uint8_t( *)[TS][TS][]) buffer; /* [SA] */
lab = (short ( *)[TS][TS][])(buffer + * TS * TS);
homo = (char ( *)[TS][TS]) (buffer + * TS * TS); for (top = ; top < height; top += TS - )
for (left = ; left < width; left += TS - )
{
memset (rgb, , * TS * TS); /* Interpolate green horizontally and vertically: */
for (row = top < ? : top; row < top + TS && row < height - ; row++)
{
col = left + (FC(row, left) == );
if (col < ) col += ;
for (fc = FC(row, col); col < left + TS && col < width - ; col += )
{
pix = (uint8_t ( *)[])dst + (row * width + col); /* [SA] */
val = ((pix[-][] + pix[][fc] + pix[][]) *
- pix[-][fc] - pix[][fc]) >> ;
rgb[][row-top][col-left][] = ULIM(val, pix[-][], pix[][]);
val = ((pix[-width][] + pix[][fc] + pix[width][]) *
- pix[-*width][fc] - pix[*width][fc]) >> ;
rgb[][row-top][col-left][] = ULIM(val, pix[-width][], pix[width][]);
}
}
/* Interpolate red and blue, and convert to CIELab: */
for (d = ; d < ; d++)
for (row = top + ; row < top + TS - && row < height - ; row++)
for (col = left + ; col < left + TS - && col < width - ; col++)
{
pix = (uint8_t ( *)[])dst + (row * width + col); /* [SA] */
rix = &rgb[d][row-top][col-left];
if ((c = - FC(row, col)) == )
{
c = FC(row + , col);
val = pix[][] + (( pix[-][-c] + pix[][-c]
- rix[-][] - rix[][] ) >> );
rix[][-c] = CLIPOUT(val); /* [SA] */
val = pix[][] + (( pix[-width][c] + pix[width][c]
- rix[-TS][] - rix[TS][] ) >> );
}
else
val = rix[][] + (( pix[-width-][c] + pix[-width+][c]
+ pix[+width-][c] + pix[+width+][c]
- rix[-TS-][] - rix[-TS+][]
- rix[+TS-][] - rix[+TS+][] + ) >> );
rix[][c] = CLIPOUT(val); /* [SA] */
c = FC(row, col);
rix[][c] = pix[][c];
rix16[] = rix[][]; /* [SA] */
rix16[] = rix[][]; /* [SA] */
rix16[] = rix[][]; /* [SA] */
cam_to_cielab (rix16, flab); /* [SA] */
FORC3 lab[d][row-top][col-left][c] = * flab[c];
}
/* Build homogeneity maps from the CIELab images: */
memset (homo, , * TS * TS);
for (row = top + ; row < top + TS - && row < height; row++)
{
tr = row - top;
for (col = left + ; col < left + TS - && col < width; col++)
{
tc = col - left;
for (d = ; d < ; d++)
for (i = ; i < ; i++)
ldiff[d][i] = ABS(lab[d][tr][tc][] - lab[d][tr][tc+dir[i]][]);
leps = MIN(MAX(ldiff[][], ldiff[][]),
MAX(ldiff[][], ldiff[][]));
for (d = ; d < ; d++)
for (i = ; i < ; i++)
if (i >> == d || ldiff[d][i] <= leps)
abdiff[d][i] = SQR(lab[d][tr][tc][] - lab[d][tr][tc+dir[i]][])
+ SQR(lab[d][tr][tc][] - lab[d][tr][tc+dir[i]][]);
abeps = MIN(MAX(abdiff[][], abdiff[][]),
MAX(abdiff[][], abdiff[][]));
for (d = ; d < ; d++)
for (i = ; i < ; i++)
if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
homo[d][tr][tc]++;
}
}
/* Combine the most homogenous pixels for the final result: */
for (row = top + ; row < top + TS - && row < height - ; row++)
{
tr = row - top;
for (col = left + ; col < left + TS - && col < width - ; col++)
{
tc = col - left;
for (d = ; d < ; d++)
for (hm[d] = , i = tr - ; i <= tr + ; i++)
for (j = tc - ; j <= tc + ; j++)
hm[d] += homo[d][i][j];
if (hm[] != hm[])
FORC3 dst[(row*width+col)* + c] = CLIPOUT(rgb[hm[] > hm[]][tr][tc][c]); /* [SA] */
else
FORC3 dst[(row*width+col)* + c] =
CLIPOUT((rgb[][tr][tc][c] + rgb[][tr][tc][c]) >> ); /* [SA] */
}
}
}
free (buffer); return DC1394_SUCCESS;
} dc1394error_t dc1394_bayer_AHD_uint16(const uint16_t *restrict bayer, uint16_t *restrict dst, int sx, int sy, dc1394color_filter_t pattern, int bits)
{
int i, j, top, left, row, col, tr, tc, fc, c, d, val, hm[];
/* the following has the same type as the image */
uint16_t (*pix)[], (*rix)[]; /* [SA] */
static const int dir[] = { -, , -TS, TS };
unsigned ldiff[][], abdiff[][], leps, abeps;
float flab[];
uint16_t (*rgb)[TS][TS][]; /* [SA] */
short (*lab)[TS][TS][];
char (*homo)[TS][TS], *buffer; /* start - new code for libdc1394 */
uint32_t filters;
const int height = sy, width = sx;
int x, y; if (ahd_inited == DC1394_FALSE)
{
/* WARNING: this might not be multi-processor safe */
cam_to_cielab (NULL, NULL);
ahd_inited = DC1394_TRUE;
} switch(pattern)
{
case DC1394_COLOR_FILTER_BGGR:
filters = 0x16161616;
break;
case DC1394_COLOR_FILTER_GRBG:
filters = 0x61616161;
break;
case DC1394_COLOR_FILTER_RGGB:
filters = 0x94949494;
break;
case DC1394_COLOR_FILTER_GBRG:
filters = 0x49494949;
break;
default:
return DC1394_INVALID_COLOR_FILTER;
} /* fill-in destination with known exact values */
for (y = ; y < height; y++)
{
for (x = ; x < width; x++)
{
int channel = FC(y, x);
dst[(y*width+x)* + channel] = bayer[y*width+x];
}
}
/* end - new code for libdc1394 */ /* start - code from border_interpolate(int border) */
{
int border = ;
unsigned row, col, y, x, f, c, sum[]; for (row = ; row < height; row++)
for (col = ; col < width; col++)
{
if (col == border && row >= border && row < height - border)
col = width - border;
memset (sum, , sizeof sum);
for (y = row - ; y != row + ; y++)
for (x = col - ; x != col + ; x++)
if (y < height && x < width)
{
f = FC(y, x);
sum[f] += dst[(y*width+x)* + f]; /* [SA] */
sum[f+]++;
}
f = FC(row, col);
FORC3 if (c != f && sum[c+]) /* [SA] */
dst[(row*width+col)* + c] = sum[c] / sum[c+]; /* [SA] */
}
}
/* end - code from border_interpolate(int border) */ buffer = (char *) malloc ( * TS * TS); /* 1664 kB */
/* merror (buffer, "ahd_interpolate()"); */
rgb = (uint16_t( *)[TS][TS][]) buffer; /* [SA] */
lab = (short ( *)[TS][TS][])(buffer + * TS * TS);
homo = (char ( *)[TS][TS]) (buffer + * TS * TS); for (top = ; top < height; top += TS - )
for (left = ; left < width; left += TS - )
{
memset (rgb, , * TS * TS); /* Interpolate green horizontally and vertically: */
for (row = top < ? : top; row < top + TS && row < height - ; row++)
{
col = left + (FC(row, left) == );
if (col < ) col += ;
for (fc = FC(row, col); col < left + TS && col < width - ; col += )
{
pix = (uint16_t ( *)[])dst + (row * width + col); /* [SA] */
val = ((pix[-][] + pix[][fc] + pix[][]) *
- pix[-][fc] - pix[][fc]) >> ;
rgb[][row-top][col-left][] = ULIM(val, pix[-][], pix[][]);
val = ((pix[-width][] + pix[][fc] + pix[width][]) *
- pix[-*width][fc] - pix[*width][fc]) >> ;
rgb[][row-top][col-left][] = ULIM(val, pix[-width][], pix[width][]);
}
}
/* Interpolate red and blue, and convert to CIELab: */
for (d = ; d < ; d++)
for (row = top + ; row < top + TS - && row < height - ; row++)
for (col = left + ; col < left + TS - && col < width - ; col++)
{
pix = (uint16_t ( *)[])dst + (row * width + col); /* [SA] */
rix = &rgb[d][row-top][col-left];
if ((c = - FC(row, col)) == )
{
c = FC(row + , col);
val = pix[][] + (( pix[-][-c] + pix[][-c]
- rix[-][] - rix[][] ) >> );
rix[][-c] = CLIPOUT16(val, bits); /* [SA] */
val = pix[][] + (( pix[-width][c] + pix[width][c]
- rix[-TS][] - rix[TS][] ) >> );
}
else
val = rix[][] + (( pix[-width-][c] + pix[-width+][c]
+ pix[+width-][c] + pix[+width+][c]
- rix[-TS-][] - rix[-TS+][]
- rix[+TS-][] - rix[+TS+][] + ) >> );
rix[][c] = CLIPOUT16(val, bits); /* [SA] */
c = FC(row, col);
rix[][c] = pix[][c];
cam_to_cielab (rix[], flab);
FORC3 lab[d][row-top][col-left][c] = * flab[c];
}
/* Build homogeneity maps from the CIELab images: */
memset (homo, , * TS * TS);
for (row = top + ; row < top + TS - && row < height; row++)
{
tr = row - top;
for (col = left + ; col < left + TS - && col < width; col++)
{
tc = col - left;
for (d = ; d < ; d++)
for (i = ; i < ; i++)
ldiff[d][i] = ABS(lab[d][tr][tc][] - lab[d][tr][tc+dir[i]][]);
leps = MIN(MAX(ldiff[][], ldiff[][]),
MAX(ldiff[][], ldiff[][]));
for (d = ; d < ; d++)
for (i = ; i < ; i++)
if (i >> == d || ldiff[d][i] <= leps)
abdiff[d][i] = SQR(lab[d][tr][tc][] - lab[d][tr][tc+dir[i]][])
+ SQR(lab[d][tr][tc][] - lab[d][tr][tc+dir[i]][]);
abeps = MIN(MAX(abdiff[][], abdiff[][]),
MAX(abdiff[][], abdiff[][]));
for (d = ; d < ; d++)
for (i = ; i < ; i++)
if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
homo[d][tr][tc]++;
}
}
/* Combine the most homogenous pixels for the final result: */
for (row = top + ; row < top + TS - && row < height - ; row++)
{
tr = row - top;
for (col = left + ; col < left + TS - && col < width - ; col++)
{
tc = col - left;
for (d = ; d < ; d++)
for (hm[d] = , i = tr - ; i <= tr + ; i++)
for (j = tc - ; j <= tc + ; j++)
hm[d] += homo[d][i][j];
if (hm[] != hm[])
FORC3 dst[(row*width+col)* + c] = CLIPOUT16(rgb[hm[] > hm[]][tr][tc][c], bits); /* [SA] */
else
FORC3 dst[(row*width+col)* + c] =
CLIPOUT16((rgb[][tr][tc][c] + rgb[][tr][tc][c]) >> , bits); /* [SA] */
}
}
}
free (buffer); return DC1394_SUCCESS;
} dc1394error_t dc1394_bayer_decoding_8bit(const uint8_t *restrict bayer, uint8_t *restrict rgb, uint32_t sx, uint32_t sy, dc1394color_filter_t tile, dc1394bayer_method_t method)
{
switch (method)
{
case DC1394_BAYER_METHOD_NEAREST:
return dc1394_bayer_NearestNeighbor(bayer, rgb, sx, sy, tile);
case DC1394_BAYER_METHOD_SIMPLE:
return dc1394_bayer_Simple(bayer, rgb, sx, sy, tile);
case DC1394_BAYER_METHOD_BILINEAR:
return dc1394_bayer_Bilinear(bayer, rgb, sx, sy, tile);
case DC1394_BAYER_METHOD_HQLINEAR:
return dc1394_bayer_HQLinear(bayer, rgb, sx, sy, tile);
case DC1394_BAYER_METHOD_DOWNSAMPLE:
return dc1394_bayer_Downsample(bayer, rgb, sx, sy, tile);
case DC1394_BAYER_METHOD_EDGESENSE:
return dc1394_bayer_EdgeSense(bayer, rgb, sx, sy, tile);
case DC1394_BAYER_METHOD_VNG:
return dc1394_bayer_VNG(bayer, rgb, sx, sy, tile);
case DC1394_BAYER_METHOD_AHD:
return dc1394_bayer_AHD(bayer, rgb, sx, sy, tile);
default:
return DC1394_INVALID_BAYER_METHOD;
} } dc1394error_t dc1394_bayer_decoding_16bit(const uint16_t *restrict bayer, uint16_t *restrict rgb, uint32_t sx, uint32_t sy, dc1394color_filter_t tile, dc1394bayer_method_t method, uint32_t bits)
{
switch (method)
{
case DC1394_BAYER_METHOD_NEAREST:
return dc1394_bayer_NearestNeighbor_uint16(bayer, rgb, sx, sy, tile, bits);
case DC1394_BAYER_METHOD_SIMPLE:
return dc1394_bayer_Simple_uint16(bayer, rgb, sx, sy, tile, bits);
case DC1394_BAYER_METHOD_BILINEAR:
return dc1394_bayer_Bilinear_uint16(bayer, rgb, sx, sy, tile, bits);
case DC1394_BAYER_METHOD_HQLINEAR:
return dc1394_bayer_HQLinear_uint16(bayer, rgb, sx, sy, tile, bits);
case DC1394_BAYER_METHOD_DOWNSAMPLE:
return dc1394_bayer_Downsample_uint16(bayer, rgb, sx, sy, tile, bits);
case DC1394_BAYER_METHOD_EDGESENSE:
return dc1394_bayer_EdgeSense_uint16(bayer, rgb, sx, sy, tile, bits);
case DC1394_BAYER_METHOD_VNG:
return dc1394_bayer_VNG_uint16(bayer, rgb, sx, sy, tile, bits);
case DC1394_BAYER_METHOD_AHD:
return dc1394_bayer_AHD_uint16(bayer, rgb, sx, sy, tile, bits);
default:
return DC1394_INVALID_BAYER_METHOD;
} } #if 0
dc1394error_t Adapt_buffer_bayer(dc1394video_frame_t *in, dc1394video_frame_t *out, dc1394bayer_method_t method)
{
uint32_t bpp; // conversions will halve the buffer size if the method is DOWNSAMPLE:
out->size[] = in->size[];
out->size[] = in->size[];
if (method == DC1394_BAYER_METHOD_DOWNSAMPLE)
{
out->size[] /= ; // ODD SIZE CASES NOT TAKEN INTO ACCOUNT
out->size[] /= ;
} // as a convention we divide the image position by two in the case of a DOWNSAMPLE:
out->position[] = in->position[];
out->position[] = in->position[];
if (method == DC1394_BAYER_METHOD_DOWNSAMPLE)
{
out->position[] /= ;
out->position[] /= ;
} // the destination color coding is ALWAYS RGB. Set this.
if ( (in->color_coding == DC1394_COLOR_CODING_RAW16) ||
(in->color_coding == DC1394_COLOR_CODING_MONO16) )
out->color_coding = DC1394_COLOR_CODING_RGB16;
else
out->color_coding = DC1394_COLOR_CODING_RGB8; // keep the color filter value in all cases. If the format is not raw it will not be further used anyway
out->color_filter = in->color_filter; // The output is never YUV, hence nothing to do about YUV byte order // bit depth is conserved for 16 bit and set to 8bit for 8bit:
if ( (in->color_coding == DC1394_COLOR_CODING_RAW16) ||
(in->color_coding == DC1394_COLOR_CODING_MONO16) )
out->data_depth = in->data_depth;
else
out->data_depth = ; // don't know what to do with stride... >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<<
// out->stride=?? // the video mode should not change. Color coding and other stuff can be accessed in specific fields of this struct
out->video_mode = in->video_mode; // padding is kept:
out->padding_bytes = in->padding_bytes; // image bytes changes: >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<<
dc1394_get_color_coding_bit_size(out->color_coding, &bpp);
out->image_bytes = (out->size[] * out->size[] * bpp) / ; // total is image_bytes + padding_bytes
out->total_bytes = out->image_bytes + out->padding_bytes; // bytes-per-packet and packets_per_frame are internal data that can be kept as is.
out->packet_size = in->packet_size;
out->packets_per_frame = in->packets_per_frame; // timestamp, frame_behind, id and camera are copied too:
out->timestamp = in->timestamp;
out->frames_behind = in->frames_behind;
out->camera = in->camera;
out->id = in->id; // verify memory allocation:
if (out->total_bytes > out->allocated_image_bytes)
{
free(out->image);
out->image = (uint8_t *)malloc(out->total_bytes * sizeof(uint8_t));
if (out->image)
out->allocated_image_bytes = out->total_bytes * sizeof(uint8_t);
else
out->allocated_image_bytes = ;
} // Copy padding bytes:
if(out->image)
memcpy(&(out->image[out->image_bytes]), &(in->image[in->image_bytes]), out->padding_bytes); out->little_endian = ; // not used before 1.32 is out.
out->data_in_padding = ; // not used before 1.32 is out. if(out->image)
return DC1394_SUCCESS; return DC1394_MEMORY_ALLOCATION_FAILURE;
} dc1394error_t dc1394_debayer_frames(dc1394video_frame_t *in, dc1394video_frame_t *out, dc1394bayer_method_t method)
{
if ((method < DC1394_BAYER_METHOD_MIN) || (method > DC1394_BAYER_METHOD_MAX))
return DC1394_INVALID_BAYER_METHOD; switch (in->color_coding)
{
case DC1394_COLOR_CODING_RAW8:
case DC1394_COLOR_CODING_MONO8: if(DC1394_SUCCESS != Adapt_buffer_bayer(in, out, method))
return DC1394_MEMORY_ALLOCATION_FAILURE; switch (method)
{
case DC1394_BAYER_METHOD_NEAREST:
return dc1394_bayer_NearestNeighbor(in->image, out->image, in->size[], in->size[], in->color_filter);
case DC1394_BAYER_METHOD_SIMPLE:
return dc1394_bayer_Simple(in->image, out->image, in->size[], in->size[], in->color_filter);
case DC1394_BAYER_METHOD_BILINEAR:
return dc1394_bayer_Bilinear(in->image, out->image, in->size[], in->size[], in->color_filter);
case DC1394_BAYER_METHOD_HQLINEAR:
return dc1394_bayer_HQLinear(in->image, out->image, in->size[], in->size[], in->color_filter);
case DC1394_BAYER_METHOD_DOWNSAMPLE:
return dc1394_bayer_Downsample(in->image, out->image, in->size[], in->size[], in->color_filter);
case DC1394_BAYER_METHOD_EDGESENSE:
return dc1394_bayer_EdgeSense(in->image, out->image, in->size[], in->size[], in->color_filter);
case DC1394_BAYER_METHOD_VNG:
return dc1394_bayer_VNG(in->image, out->image, in->size[], in->size[], in->color_filter);
case DC1394_BAYER_METHOD_AHD:
return dc1394_bayer_AHD(in->image, out->image, in->size[], in->size[], in->color_filter);
}
break;
case DC1394_COLOR_CODING_MONO16:
case DC1394_COLOR_CODING_RAW16: if(DC1394_SUCCESS != Adapt_buffer_bayer(in, out, method))
return DC1394_MEMORY_ALLOCATION_FAILURE; switch (method)
{
case DC1394_BAYER_METHOD_NEAREST:
return dc1394_bayer_NearestNeighbor_uint16((uint16_t *)in->image, (uint16_t *)out->image, in->size[], in->size[], in->color_filter, in->data_depth);
case DC1394_BAYER_METHOD_SIMPLE:
return dc1394_bayer_Simple_uint16((uint16_t *)in->image, (uint16_t *)out->image, in->size[], in->size[], in->color_filter, in->data_depth);
case DC1394_BAYER_METHOD_BILINEAR:
return dc1394_bayer_Bilinear_uint16((uint16_t *)in->image, (uint16_t *)out->image, in->size[], in->size[], in->color_filter, in->data_depth);
case DC1394_BAYER_METHOD_HQLINEAR:
return dc1394_bayer_HQLinear_uint16((uint16_t *)in->image, (uint16_t *)out->image, in->size[], in->size[], in->color_filter, in->data_depth);
case DC1394_BAYER_METHOD_DOWNSAMPLE:
return dc1394_bayer_Downsample_uint16((uint16_t *)in->image, (uint16_t *)out->image, in->size[], in->size[], in->color_filter, in->data_depth);
case DC1394_BAYER_METHOD_EDGESENSE:
return dc1394_bayer_EdgeSense_uint16((uint16_t *)in->image, (uint16_t *)out->image, in->size[], in->size[], in->color_filter, in->data_depth);
case DC1394_BAYER_METHOD_VNG:
return dc1394_bayer_VNG_uint16((uint16_t *)in->image, (uint16_t *)out->image, in->size[], in->size[], in->color_filter, in->data_depth);
case DC1394_BAYER_METHOD_AHD:
return dc1394_bayer_AHD_uint16((uint16_t *)in->image, (uint16_t *)out->image, in->size[], in->size[], in->color_filter, in->data_depth);
}
break;
default:
return DC1394_FUNCTION_NOT_SUPPORTED;
} return DC1394_SUCCESS;
}
#endif // bmp types: short = 3, int = 4
// Tags: ( 2-byte tag ) ( 2-byte type ) ( 4-byte count ) ( 4-byte data )
// 0100 0003 0000 0001 0064 0000
// | | | |
// tag --+ | | |
// short int -----+ | |
// one value ----------+ |
// value of 100 -----------------+
//
#define TIFF_HDR_NUM_ENTRY 8
#define TIFF_HDR_SIZE 10+TIFF_HDR_NUM_ENTRY*12
uint8_t tiff_header[TIFF_HDR_SIZE] =
{
// I I 42
0x49, 0x49, 0x2a, 0x00,
// ( offset to tags, 0 )
0x08, 0x00, 0x00, 0x00,
// ( num tags )
0x08, 0x00,
// ( newsubfiletype, 0 full-image )
0xfe, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// ( image width )
0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// ( image height )
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// ( bits per sample )
0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// ( Photometric Interpretation, 2 = RGB )
0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
// ( Strip offsets, 8 )
0x11, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
// ( samples per pixel, 3 - RGB)
0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
// ( Strip byte count )
0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
uint8_t *put_tiff(uint8_t *rgb, uint32_t width, uint32_t height, uint16_t bpp)
{
uint32_t ulTemp = ;
uint16_t sTemp = ;
printf("%s\n", __func__);
memcpy(rgb, tiff_header, TIFF_HDR_SIZE); sTemp = TIFF_HDR_NUM_ENTRY;
memcpy(rgb + , &sTemp, ); memcpy(rgb + + * + , &width, );
memcpy(rgb + + * + , &height, );
memcpy(rgb + + * + , &bpp, ); // strip byte count
ulTemp = width * height * (bpp / ) * ;
memcpy(rgb + + * + , &ulTemp, ); //strip offset
sTemp = TIFF_HDR_SIZE;
memcpy(rgb + + * + , &sTemp, );
return rgb + TIFF_HDR_SIZE;
}; #define ALIGN(x, n) (((x)+(n)-1)&~((n)-1))
typedef struct
{
unsigned short bfType; /* 说明文件的类型 */
unsigned int bfSize; /* 说明文件的大小,用字节为单位 */
unsigned short bfReserved1; /* 保留,设置为0 */
unsigned short bfReserved2; /* 保留,设置为0 */
unsigned int bfOffsetBytes; /* 说明从BITMAPFILEHEADER结构开始到实际的图像数据之间的字节偏移量 */
}__attribute__((gcc_struct, packed)) bfh_t; //14字节,但是sizeof计算长度时为16字节 typedef struct
{
unsigned int biSize; /* 说明结构体所需字节数 */
unsigned int biWidth; /* 以像素为单位说明图像的宽度 */
unsigned int biHeight; /* 以像素为单位说明图像的高度 */
unsigned short biPlanes; /* 说明位面数,必须为1 */
unsigned short biBitCount; /* 说明位数/像素,1、2、4、8、24 */
unsigned int biCompression; /* 说明图像是否压缩及压缩类型BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS */
unsigned int biSizeImage; /* 以字节为单位说明图像大小,必须是4的整数倍*/
unsigned int biXPixelsPerMeter; /*目标设备的水平分辨率,像素/米 */
unsigned int biYPixelsPerMeter; /*目标设备的垂直分辨率,像素/米 */
unsigned int biClrUsed; /* 说明图像实际用到的颜色数,如果为0,则颜色数为2的biBitCount次方 */
unsigned int biClrImportant; /*说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。*/
}__attribute__((gcc_struct, packed)) bhi_t; //40字节 int put_bmp_hdr(unsigned char *base, uint32_t w, uint32_t h)
{
bfh_t *bfh_out = base;
bhi_t *bhi_out = base + sizeof(bfh_t); bfh_out->bfType = 0x4d42;
bfh_out->bfSize = ALIGN(w*, ) * h + ;
bfh_out->bfReserved1 = ;
bfh_out->bfReserved2 = ;
bfh_out->bfOffsetBytes = ;
bhi_out->biSize = ;
bhi_out->biWidth = w;
bhi_out->biHeight = h;
bhi_out->biPlanes = ;
bhi_out->biBitCount = ;
bhi_out->biCompression = ;
bhi_out->biSizeImage = ALIGN(w*, ) * h;
bhi_out->biXPixelsPerMeter = ;
bhi_out->biYPixelsPerMeter = ;
bhi_out->biClrUsed = ;
bhi_out->biClrImportant = ;
return ;
} dc1394bayer_method_t getMethod(char *m)
{
if( strcmp(m, "NEAREST") == )
return DC1394_BAYER_METHOD_NEAREST;
if( strcmp(m, "SIMPLE") == )
return DC1394_BAYER_METHOD_SIMPLE;
if( strcmp(m, "BILINEAR") == )
return DC1394_BAYER_METHOD_BILINEAR;
if( strcmp(m, "HQLINEAR") == )
return DC1394_BAYER_METHOD_HQLINEAR;
if( strcmp(m, "DOWNSAMPLE") == )
return DC1394_BAYER_METHOD_DOWNSAMPLE;
if( strcmp(m, "EDGESENSE") == )
return DC1394_BAYER_METHOD_EDGESENSE;
if( strcmp(m, "VNG") == )
return DC1394_BAYER_METHOD_VNG;
if( strcmp(m, "AHD") == )
return DC1394_BAYER_METHOD_AHD; printf("WARNING: Unrecognized method \"%s\", defaulting to BILINEAR\n", m);
return DC1394_BAYER_METHOD_BILINEAR;
} dc1394color_filter_t getFirstColor(char *f)
{
if( strcmp(f, "RGGB") == )
return DC1394_COLOR_FILTER_RGGB;
if( strcmp(f, "GBRG") == )
return DC1394_COLOR_FILTER_GBRG;
if( strcmp(f, "GRBG") == )
return DC1394_COLOR_FILTER_GRBG;
if( strcmp(f, "BGGR") == )
return DC1394_COLOR_FILTER_BGGR; printf("WARNING: Unrecognized first color \"%s\", defaulting to RGGB\n", f);
return DC1394_COLOR_FILTER_RGGB;
} void usage( char *name )
{
printf("usage: %s\n", name);
printf(" --input,-i input file\n");
printf(" --output,-o output file\n");
printf(" --width,-w image width (pixels)\n");
printf(" --height,-v image height (pixels)\n");
printf(" --bpp,-b bits per pixel\n");
printf(" --first,-f first pixel color: RGGB, GBRG, GRBG, BGGR\n");
printf(" --method,-m interpolation method: NEAREST, SIMPLE, BILINEAR, HQLINEAR, DOWNSAMPLE, EDGESENSE, VNG, AHD\n");
printf(" --bmp,-t add a bmp header\n");
printf(" --swap,-s if bpp == 16, swap byte order before conversion\n");
printf(" --help,-h this helpful message\n");
} int main( int argc, char **argv )
{
int in_size = , out_size = , width = , height = , bpp = ;
int first_color = DC1394_COLOR_FILTER_RGGB;
int bmp = ;
int method = DC1394_BAYER_METHOD_BILINEAR;
char *infile = NULL, *outfile = NULL;
FILE *input_fd = NULL;
FILE *output_fd = NULL;
void *bayer = NULL;
void *rgb_buf = NULL, *out_buf = NULL;
char c;
int optidx = ;
int swap = ; struct option longopt[] =
{
{"input", , NULL, 'i'},
{"output", , NULL, 'o'},
{"width", , NULL, 'w'},
{"height", , NULL, 'v'},
{"help", , NULL, 'h'},
{"bpp", , NULL, 'b'},
{"first", , NULL, 'f'},
{"method", , NULL, 'm'},
{"bmp", , NULL, 't'},
{"swap", , NULL, 's'},
{, , , }
}; while ((c = getopt_long(argc, argv, "i:o:w:v:b:f:m:ths", longopt, &optidx)) != -)
{
switch ( c )
{
case 'i':
infile = strdup( optarg );
break;
case 'o':
outfile = strdup( optarg );
break;
case 'w':
width = strtol( optarg, NULL, );
break;
case 'v':
height = strtol( optarg, NULL, );
break;
case 'b':
bpp = strtol( optarg, NULL, );
break;
case 'f':
first_color = getFirstColor( optarg );
break;
case 'm':
method = getMethod( optarg );
break;
case 's':
swap = ;
break;
case 't':
bmp = ;
break;
case 'h':
usage(argv[]);
return ;
break;
default:
printf("bad arg\n");
usage(argv[]);
return ;
}
}
if( infile == NULL || outfile == NULL || bpp == || width == || height == )
{
printf("Bad parameter\n");
usage(argv[]);
return ;
}
input_fd = fopen(infile, "rw+b");
if(input_fd < )
{
printf("Problem opening input: %s\n", infile);
return ;
}
output_fd = fopen(outfile, "w+b");
if(output_fd < )
{
printf("Problem opening output: %s\n", outfile);
return ;
}
fseek(input_fd, , SEEK_END);
in_size = ftell(input_fd);
fseek(input_fd, , SEEK_SET);
if(in_size <= )
{
printf("%s@%d lseek %d err, cur %d errno %d\n", __func__, __LINE__, in_size, lseek(input_fd, 0L, SEEK_CUR), errno);
return -;
} out_size = width * height * (bpp / ) * + bmp;
bayer = malloc(in_size);
if(bayer == NULL)
{
printf("%s@%d malloc(%d) err\n", __func__, __LINE__, in_size);
return -;
}
if ((fread(bayer, , in_size, input_fd)) < in_size)
{
printf("%s@%d err\n", __func__, __LINE__);
return -;
}
out_buf = rgb_buf = malloc(out_size);
if(bmp) rgb_buf += bmp;
if(out_buf == NULL)
{
printf("%s@%d malloc(%d) err\n", __func__, __LINE__, out_size);
return -;
}
if(bmp)
{
put_bmp_hdr(out_buf, width, height);
}
switch(bpp)
{
case :
dc1394_bayer_decoding_8bit((const uint8_t *)bayer, (uint8_t *)rgb_buf, width, height, first_color, method);
break;
case :
default:
if(swap)
{
uint8_t tmp = ;
uint32_t i = ;
for(i = ; i < in_size; i += )
{
tmp = *(((uint8_t *)bayer) + i);
*(((uint8_t *)bayer) + i) = *(((uint8_t *)bayer) + i + );
*(((uint8_t *)bayer) + i + ) = tmp;
}
}
dc1394_bayer_decoding_16bit((const uint16_t *)bayer, (uint16_t *)rgb_buf, width, height, first_color, method, bpp);
break;
}
if ((fwrite(out_buf, , out_size, output_fd)) == )
{
printf("%s@%d err\n", __func__, __LINE__);
return -;
} free(bayer);
free(out_buf); fclose(input_fd);
fclose(output_fd); return ;
}

bayer2bmp的更多相关文章

随机推荐

  1. 基于UDP协议的socket套接字编程

    目录 一.UDP套接字简单示例 1.1 服务端 二.客户端 三.UPD套接字无粘包问题 3.1 服务端 3.2 客户端 四.qq聊天 4.1 服务端 4.2 客户端1 4.3 客户端2 4.4 运行结 ...

  2. COM 编程基础

    DirectX 采用了 COM 标准.而 DirectShow 是一套完全基于 COM 的应用系统.要想深入学习 DirectShow,掌握一些 COM 编程的基础知识是必不可少的. 一.COM 是什 ...

  3. 使用pymysql模块进行封装,自动化不可或缺的数据库校验

    import pymysql class HandleMysql: ''' 定义一个mysql处理类 ''' def __init__(self, hostname, username, passwo ...

  4. ubuntu 16.04无法连接网络;双系统无法上网;连接已断开,你现在处于断开状态

    先描述一一下我的问题,若和你的一样,请继续往下看. 我是在原有Windows7系统的台式计算机中安装了ubuntu 16.04,所以目前这台计算机是双系统.打开Windows系统时有线网络正常链接.但 ...

  5. MySQL-8.0.18 引入了破坏性变更

    MySQL-8.0.18 引入了破坏性变更 变更日志里面有这样一项 When the server is run with --initialize, there is no reason to lo ...

  6. 前端之json,ajax和jsonp

    json json是 JavaScript Object Notation 的首字母缩写,单词的意思是javascript对象表示法,这里说的json指的是类似于javascript对象的一种数据格式 ...

  7. 前端之javascript1

    js介绍和js引入页面 学习前端脚本语言javascript的基本概念.页面引入方式.获取页面元素及操作元素属性的技巧,学习函数的基本定义方法和使用方法. JavaScript介绍 JavaScrip ...

  8. 微信网站登录doem

    直接上代码 namespace CloudPrj.WeiXin {     public partial class index : System.Web.UI.Page     {         ...

  9. JAVA 设置模块间的依赖关系

    项目目录概况 Demo01项目 Test01.java package com.sam.demo01; public class Test01 { public void ShowTest01() { ...

  10. Typescript基础(3)——类

    前言 今天继续typescript的学习,开始ts类的学习. 类 类的实现 在ES6中新增了类的概念.我们先看ES6中类的实现. class Person { constructor(name,age ...