📄 cpia.c
字号:
static int free_frame_buf(struct cam_data *cam){ int i; rvfree(cam->frame_buf, FRAME_NUM*CPIA_MAX_FRAME_SIZE); cam->frame_buf = 0; for (i=0; i < FRAME_NUM; i++) cam->frame[i].data = NULL; return 0;}static inline void free_frames(struct cpia_frame frame[FRAME_NUM]){ int i; for (i=0; i < FRAME_NUM; i++) frame[i].state = FRAME_UNUSED; return;}/********************************************************************** * * General functions * **********************************************************************//* send an arbitrary command to the camera */static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d){ int retval, datasize; u8 cmd[8], data[8]; switch(command) { case CPIA_COMMAND_GetCPIAVersion: case CPIA_COMMAND_GetPnPID: case CPIA_COMMAND_GetCameraStatus: case CPIA_COMMAND_GetVPVersion: datasize=8; break; case CPIA_COMMAND_GetColourParams: case CPIA_COMMAND_GetColourBalance: case CPIA_COMMAND_GetExposure: down(&cam->param_lock); datasize=8; break; case CPIA_COMMAND_ReadMCPorts: case CPIA_COMMAND_ReadVCRegs: datasize = 4; break; default: datasize=0; break; } cmd[0] = command>>8; cmd[1] = command&0xff; cmd[2] = a; cmd[3] = b; cmd[4] = c; cmd[5] = d; cmd[6] = datasize; cmd[7] = 0; retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data); if (retval) { DBG("%x - failed, retval=%d\n", command, retval); if (command == CPIA_COMMAND_GetColourParams || command == CPIA_COMMAND_GetColourBalance || command == CPIA_COMMAND_GetExposure) up(&cam->param_lock); } else { switch(command) { case CPIA_COMMAND_GetCPIAVersion: cam->params.version.firmwareVersion = data[0]; cam->params.version.firmwareRevision = data[1]; cam->params.version.vcVersion = data[2]; cam->params.version.vcRevision = data[3]; break; case CPIA_COMMAND_GetPnPID: cam->params.pnpID.vendor = data[0]+(((u16)data[1])<<8); cam->params.pnpID.product = data[2]+(((u16)data[3])<<8); cam->params.pnpID.deviceRevision = data[4]+(((u16)data[5])<<8); break; case CPIA_COMMAND_GetCameraStatus: cam->params.status.systemState = data[0]; cam->params.status.grabState = data[1]; cam->params.status.streamState = data[2]; cam->params.status.fatalError = data[3]; cam->params.status.cmdError = data[4]; cam->params.status.debugFlags = data[5]; cam->params.status.vpStatus = data[6]; cam->params.status.errorCode = data[7]; break; case CPIA_COMMAND_GetVPVersion: cam->params.vpVersion.vpVersion = data[0]; cam->params.vpVersion.vpRevision = data[1]; cam->params.vpVersion.cameraHeadID = data[2]+(((u16)data[3])<<8); break; case CPIA_COMMAND_GetColourParams: cam->params.colourParams.brightness = data[0]; cam->params.colourParams.contrast = data[1]; cam->params.colourParams.saturation = data[2]; up(&cam->param_lock); break; case CPIA_COMMAND_GetColourBalance: cam->params.colourBalance.redGain = data[0]; cam->params.colourBalance.greenGain = data[1]; cam->params.colourBalance.blueGain = data[2]; up(&cam->param_lock); break; case CPIA_COMMAND_GetExposure: cam->params.exposure.gain = data[0]; cam->params.exposure.fineExp = data[1]; cam->params.exposure.coarseExpLo = data[2]; cam->params.exposure.coarseExpHi = data[3]; cam->params.exposure.redComp = data[4]; cam->params.exposure.green1Comp = data[5]; cam->params.exposure.green2Comp = data[6]; cam->params.exposure.blueComp = data[7]; up(&cam->param_lock); break; case CPIA_COMMAND_ReadMCPorts: if (!cam->params.qx3.qx3_detected) break; /* test button press */ cam->params.qx3.button = ((data[1] & 0x02) == 0); if (cam->params.qx3.button) { /* button pressed - unlock the latch */ do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xDF,0xDF,0); do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xFF,0xFF,0); } /* test whether microscope is cradled */ cam->params.qx3.cradled = ((data[2] & 0x40) == 0); break; default: break; } } return retval;}/* send a command to the camera with an additional data transaction */static int do_command_extended(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d, u8 e, u8 f, u8 g, u8 h, u8 i, u8 j, u8 k, u8 l){ int retval; u8 cmd[8], data[8]; cmd[0] = command>>8; cmd[1] = command&0xff; cmd[2] = a; cmd[3] = b; cmd[4] = c; cmd[5] = d; cmd[6] = 8; cmd[7] = 0; data[0] = e; data[1] = f; data[2] = g; data[3] = h; data[4] = i; data[5] = j; data[6] = k; data[7] = l; retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data); if (retval) DBG("%x - failed\n", command); return retval;}/********************************************************************** * * Colorspace conversion * **********************************************************************/#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)static int convert420(unsigned char *yuv, unsigned char *rgb, int out_fmt, int linesize, int mmap_kludge){ int y, u, v, r, g, b, y1; /* Odd lines use the same u and v as the previous line. * Because of compression, it is necessary to get this * information from the decoded image. */ switch(out_fmt) { case VIDEO_PALETTE_RGB555: y = (*yuv++ - 16) * 76310; y1 = (*yuv - 16) * 76310; r = ((*(rgb+1-linesize)) & 0x7c) << 1; g = ((*(rgb-linesize)) & 0xe0) >> 4 | ((*(rgb+1-linesize)) & 0x03) << 6; b = ((*(rgb-linesize)) & 0x1f) << 3; u = (-53294 * r - 104635 * g + 157929 * b) / 5756495; v = (157968 * r - 132278 * g - 25690 * b) / 5366159; r = 104635 * v; g = -25690 * u - 53294 * v; b = 132278 * u; *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3); *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6); *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3); *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6); return 4; case VIDEO_PALETTE_RGB565: y = (*yuv++ - 16) * 76310; y1 = (*yuv - 16) * 76310; r = (*(rgb+1-linesize)) & 0xf8; g = ((*(rgb-linesize)) & 0xe0) >> 3 | ((*(rgb+1-linesize)) & 0x07) << 5; b = ((*(rgb-linesize)) & 0x1f) << 3; u = (-53294 * r - 104635 * g + 157929 * b) / 5756495; v = (157968 * r - 132278 * g - 25690 * b) / 5366159; r = 104635 * v; g = -25690 * u - 53294 * v; b = 132278 * u; *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3); *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5); *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3); *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5); return 4; break; case VIDEO_PALETTE_RGB24: case VIDEO_PALETTE_RGB32: y = (*yuv++ - 16) * 76310; y1 = (*yuv - 16) * 76310; if (mmap_kludge) { r = *(rgb+2-linesize); g = *(rgb+1-linesize); b = *(rgb-linesize); } else { r = *(rgb-linesize); g = *(rgb+1-linesize); b = *(rgb+2-linesize); } u = (-53294 * r - 104635 * g + 157929 * b) / 5756495; v = (157968 * r - 132278 * g - 25690 * b) / 5366159; r = 104635 * v; g = -25690 * u + -53294 * v; b = 132278 * u; if (mmap_kludge) { *rgb++ = LIMIT(b+y); *rgb++ = LIMIT(g+y); *rgb++ = LIMIT(r+y); if(out_fmt == VIDEO_PALETTE_RGB32) rgb++; *rgb++ = LIMIT(b+y1); *rgb++ = LIMIT(g+y1); *rgb = LIMIT(r+y1); } else { *rgb++ = LIMIT(r+y); *rgb++ = LIMIT(g+y); *rgb++ = LIMIT(b+y); if(out_fmt == VIDEO_PALETTE_RGB32) rgb++; *rgb++ = LIMIT(r+y1); *rgb++ = LIMIT(g+y1); *rgb = LIMIT(b+y1); } if(out_fmt == VIDEO_PALETTE_RGB32) return 8; return 6; case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUYV: y = *yuv++; u = *(rgb+1-linesize); y1 = *yuv; v = *(rgb+3-linesize); *rgb++ = y; *rgb++ = u; *rgb++ = y1; *rgb = v; return 4; case VIDEO_PALETTE_UYVY: u = *(rgb-linesize); y = *yuv++; v = *(rgb+2-linesize); y1 = *yuv; *rgb++ = u; *rgb++ = y; *rgb++ = v; *rgb = y1; return 4; case VIDEO_PALETTE_GREY: *rgb++ = *yuv++; *rgb = *yuv; return 2; default: DBG("Empty: %d\n", out_fmt); return 0; }}static int yuvconvert(unsigned char *yuv, unsigned char *rgb, int out_fmt, int in_uyvy, int mmap_kludge){ int y, u, v, r, g, b, y1; switch(out_fmt) { case VIDEO_PALETTE_RGB555: case VIDEO_PALETTE_RGB565: case VIDEO_PALETTE_RGB24: case VIDEO_PALETTE_RGB32: if (in_uyvy) { u = *yuv++ - 128; y = (*yuv++ - 16) * 76310; v = *yuv++ - 128; y1 = (*yuv - 16) * 76310; } else { y = (*yuv++ - 16) * 76310; u = *yuv++ - 128; y1 = (*yuv++ - 16) * 76310; v = *yuv - 128; } r = 104635 * v; g = -25690 * u + -53294 * v; b = 132278 * u; break; default: y = *yuv++; u = *yuv++; y1 = *yuv++; v = *yuv; /* Just to avoid compiler warnings */ r = 0; g = 0; b = 0; break; } switch(out_fmt) { case VIDEO_PALETTE_RGB555: *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3); *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6); *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3); *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6); return 4; case VIDEO_PALETTE_RGB565: *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3); *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5); *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3); *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5); return 4; case VIDEO_PALETTE_RGB24: if (mmap_kludge) { *rgb++ = LIMIT(b+y); *rgb++ = LIMIT(g+y); *rgb++ = LIMIT(r+y); *rgb++ = LIMIT(b+y1); *rgb++ = LIMIT(g+y1); *rgb = LIMIT(r+y1); } else { *rgb++ = LIMIT(r+y); *rgb++ = LIMIT(g+y); *rgb++ = LIMIT(b+y); *rgb++ = LIMIT(r+y1); *rgb++ = LIMIT(g+y1); *rgb = LIMIT(b+y1); } return 6; case VIDEO_PALETTE_RGB32: if (mmap_kludge) { *rgb++ = LIMIT(b+y); *rgb++ = LIMIT(g+y); *rgb++ = LIMIT(r+y); rgb++; *rgb++ = LIMIT(b+y1); *rgb++ = LIMIT(g+y1); *rgb = LIMIT(r+y1); } else { *rgb++ = LIMIT(r+y); *rgb++ = LIMIT(g+y); *rgb++ = LIMIT(b+y); rgb++; *rgb++ = LIMIT(r+y1); *rgb++ = LIMIT(g+y1); *rgb = LIMIT(b+y1); } return 8; case VIDEO_PALETTE_GREY: *rgb++ = y; *rgb = y1; return 2; case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUYV: *rgb++ = y; *rgb++ = u; *rgb++ = y1; *rgb = v; return 4; case VIDEO_PALETTE_UYVY: *rgb++ = u; *rgb++ = y; *rgb++ = v; *rgb = y1; return 4; default: DBG("Empty: %d\n", out_fmt); return 0; }}static int skipcount(int count, int fmt){ switch(fmt) { case VIDEO_PALETTE_GREY: return count; case VIDEO_PALETTE_RGB555: case VIDEO_PALETTE_RGB565: case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUYV: case VIDEO_PALETTE_UYVY: return 2*count; case VIDEO_PALETTE_RGB24: return 3*count; case VIDEO_PALETTE_RGB32: return 4*count; default: return 0; }}static int parse_picture(struct cam_data *cam, int size){ u8 *obuf, *ibuf, *end_obuf; int ll, in_uyvy, compressed, decimation, even_line, origsize, out_fmt; int rows, cols, linesize, subsample_422; /* make sure params don't change while we are decoding */ down(&cam->param_lock); obuf = cam->decompressed_frame.data; end_obuf = obuf+CPIA_MAX_FRAME_SIZE; ibuf = cam->raw_image; origsize = size; out_fmt = cam->vp.pal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -