This is basically a continuation of the work from #1002 but her for the camlibs directory. The purpose was to replace spaces as a means for indentation with tab characters. Note: there are some files which are still offending the general rule but are (mostly) consistent within themselves. I let them be for the moment. Fixing them would basically replace the whole file. Also: there are still a ton of whitespace related inconsistencies like "x=10" vs "x = 10" or "func(10)" vs "func (10)". This is a whitespace only change (if you include newlines as whitespace).
256 lines
7.4 KiB
C
256 lines
7.4 KiB
C
/****************************************************************/
|
|
/* spca50x.c - Gphoto2 library for cameras with sunplus spca50x */
|
|
/* chips */
|
|
/* */
|
|
/* Copyright 2002, 2003 Till Adam */
|
|
/* */
|
|
/* Author: Till Adam <till@adam-lilienthal.de> */
|
|
/* */
|
|
/* Pure digital support: John Maushammer <www.maushammer.com> */
|
|
/* */
|
|
/* This library is free software; you can redistribute it */
|
|
/* and/or modify it under the terms of the GNU Library General */
|
|
/* Public License as published by the Free Software Foundation; */
|
|
/* either version 2 of the License, or (at your option) any */
|
|
/* later version. */
|
|
/* */
|
|
/* This library is distributed in the hope that it will be */
|
|
/* useful, but WITHOUT ANY WARRANTY; without even the implied */
|
|
/* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
|
|
/* PURPOSE. See the GNU Library General Public License for */
|
|
/* more details. */
|
|
/* */
|
|
/* You should have received a copy of the GNU Library General */
|
|
/* Public License along with this library; if not, write to the */
|
|
/* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,*/
|
|
/* Boston, MA 02110-1301 USA */
|
|
/****************************************************************/
|
|
#define _DEFAULT_SOURCE
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include <gphoto2/gphoto2.h>
|
|
#include "libgphoto2/gphoto2-endian.h"
|
|
|
|
#include "libgphoto2/i18n.h"
|
|
|
|
#include "spca50x.h"
|
|
#include "spca50x-registers.h"
|
|
#include "spca50x-jpeg-header.h"
|
|
|
|
|
|
#define GP_MODULE "spca50x"
|
|
|
|
int
|
|
spca50x_get_firmware_revision (CameraPrivateLibrary *lib)
|
|
{
|
|
|
|
CHECK (gp_port_usb_msg_read (lib->gpdev, 0x20, 0x0, 0x0,
|
|
(char *)&(lib->fw_rev), 1));
|
|
return GP_OK;
|
|
}
|
|
|
|
int
|
|
spca50x_detect_storage_type (CameraPrivateLibrary *lib)
|
|
{
|
|
int i;
|
|
uint8_t buf[3];
|
|
|
|
for (i=0;i<3;i++)
|
|
{
|
|
buf[i] = 0; /* if no data returned, assume no capability */
|
|
CHECK (gp_port_usb_msg_read (lib->gpdev, 0x28, 0x0000,
|
|
i, (char *)&buf[i], 0x01));
|
|
}
|
|
|
|
if (buf[0]) lib->storage_media_mask |= SPCA50X_SDRAM;
|
|
if (buf[1]) lib->storage_media_mask |= SPCA50X_FLASH;
|
|
if (buf[2]) lib->storage_media_mask |= SPCA50X_CARD;
|
|
GP_DEBUG("SPCA50x: has_sdram: 0x%x has_flash 0x%x has_card: 0x%x\n",
|
|
buf[0], buf[1], buf[2]);
|
|
|
|
return GP_OK;
|
|
}
|
|
|
|
static int
|
|
spca50x_pd_enable (CameraPrivateLibrary * lib)
|
|
{
|
|
uint8_t buf[9];
|
|
uint8_t writebyte;
|
|
uint32_t bcd_serial;
|
|
uint32_t return_value;
|
|
|
|
GP_DEBUG ("Pure digital additional initialization");
|
|
CHECK (gp_port_usb_msg_read (lib->gpdev, 0x2d, 0x0000, 0x0001,
|
|
(char*)buf, 0x08));
|
|
bcd_serial = ((buf[0] & 0x0f) << 28) |
|
|
((buf[1] & 0x0f) << 24) |
|
|
((buf[2] & 0x0f) << 20) |
|
|
((buf[3] & 0x0f) << 16) |
|
|
((buf[4] & 0x0f) << 12) |
|
|
((buf[5] & 0x0f) << 8) |
|
|
((buf[6] & 0x0f) << 4) |
|
|
((buf[7] & 0x0f) << 0);
|
|
GP_DEBUG ("Camera serial number = %08x", bcd_serial);
|
|
return_value = ~bcd_serial << 2;
|
|
GP_DEBUG ("return value = %08x", return_value);
|
|
writebyte = return_value & 0xff;
|
|
CHECK (gp_port_usb_msg_write (lib->gpdev, 0x2d, 0x0000, 0x0000,
|
|
(char*)&writebyte, 0x01));
|
|
writebyte = (return_value >> 8) & 0xff;
|
|
CHECK (gp_port_usb_msg_write (lib->gpdev, 0x2d, 0x0000, 0x0001,
|
|
(char*)&writebyte, 0x01));
|
|
writebyte = (return_value >> 16) & 0xff;
|
|
CHECK (gp_port_usb_msg_write (lib->gpdev, 0x2d, 0x0000, 0x0002,
|
|
(char*)&writebyte, 0x01));
|
|
writebyte = (return_value >> 24) & 0xff;
|
|
CHECK (gp_port_usb_msg_write (lib->gpdev, 0x2d, 0x0000, 0x0003,
|
|
(char*)&writebyte, 0x01));
|
|
return GP_OK;
|
|
}
|
|
|
|
int
|
|
spca50x_reset (CameraPrivateLibrary * lib)
|
|
{
|
|
GP_DEBUG ("* spca50x_reset");
|
|
if (lib->bridge == BRIDGE_SPCA500) {
|
|
if (lib->storage_media_mask & SPCA50X_SDRAM) {
|
|
/* This is not reset but "Change Mode to Idle
|
|
* (Clear Buffer)" Cant hurt, I guess. */
|
|
CHECK (gp_port_usb_msg_write
|
|
(lib->gpdev, 0x02, 0x0000, 0x07, NULL, 0));
|
|
}
|
|
} else if (lib->fw_rev == 1) {
|
|
CHECK (gp_port_usb_msg_write
|
|
(lib->gpdev, 0x02, 0x0000, 0x0003, NULL, 0));
|
|
} else if (lib->fw_rev == 2) {
|
|
CHECK (gp_port_usb_msg_write(lib->gpdev, 0, 1,
|
|
SPCA50X_REG_AutoPbSize, NULL, 0));
|
|
CHECK (gp_port_usb_msg_write(lib->gpdev, 0, 0,
|
|
0x0d04, NULL, 0));
|
|
CHECK (gp_port_usb_msg_write(lib->gpdev, 0x1e, 0, 0, NULL, 0));
|
|
if (lib->bridge == BRIDGE_SPCA504B_PD) {
|
|
CHECK (spca50x_pd_enable (lib));
|
|
}
|
|
}
|
|
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
usleep(200000);
|
|
#endif
|
|
return GP_OK;
|
|
}
|
|
|
|
|
|
int
|
|
yuv2rgb (uint32_t y, uint32_t u, uint32_t v, uint32_t *_r, uint32_t *_g, uint32_t *_b)
|
|
{
|
|
double r, g, b;
|
|
|
|
r = (char) y + 128 + 1.402 * (char) v;
|
|
g = (char) y + 128 - 0.34414 * (char) u - 0.71414 * (char) v;
|
|
b = (char) y + 128 + 1.772 * (char) u;
|
|
|
|
if (r > 255)
|
|
r = 255;
|
|
if (g > 255)
|
|
g = 255;
|
|
if (b > 255)
|
|
b = 255;
|
|
if (r < 0)
|
|
r = 0;
|
|
if (g < 0)
|
|
g = 0;
|
|
if (b < 0)
|
|
b = 0;
|
|
|
|
*_r = r;
|
|
*_g = g;
|
|
*_b = b;
|
|
|
|
return GP_OK;
|
|
}
|
|
|
|
int
|
|
spca50x_capture (CameraPrivateLibrary * lib)
|
|
{
|
|
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
sleep (2);
|
|
#endif
|
|
CHECK (gp_port_usb_msg_write
|
|
(lib->gpdev, 0x06, 0x0000, 0x0003, NULL, 0));
|
|
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
sleep (3);
|
|
#endif
|
|
return GP_OK;
|
|
}
|
|
|
|
int
|
|
create_jpeg_from_data (uint8_t * dst, uint8_t * src, unsigned int qIndex, int w,
|
|
int h, uint8_t format, int o_size, int *size,
|
|
int omit_huffman_table, int omit_escape)
|
|
{
|
|
int i = 0;
|
|
uint8_t *start;
|
|
uint8_t value;
|
|
|
|
start = dst;
|
|
/* copy the header from the template */
|
|
memcpy (dst, SPCA50xJPGDefaultHeaderPart1,
|
|
SPCA50X_JPG_DEFAULT_HEADER_PART1_LENGTH);
|
|
|
|
/* modify quantization table */
|
|
if (qIndex >= sizeof(SPCA50xQTable)/sizeof(SPCA50xQTable[0])/2) {
|
|
gp_log(GP_LOG_ERROR,"create_jpeg_from_data","qIndex %d too large", qIndex);
|
|
return GP_ERROR;
|
|
}
|
|
memcpy (dst + 7, SPCA50xQTable[qIndex * 2], 64);
|
|
memcpy (dst + 72, SPCA50xQTable[qIndex * 2 + 1], 64);
|
|
|
|
dst += SPCA50X_JPG_DEFAULT_HEADER_PART1_LENGTH;
|
|
|
|
/* copy Huffman table */
|
|
if (!omit_huffman_table) {
|
|
memcpy (dst, SPCA50xJPGDefaultHeaderPart2,
|
|
SPCA50X_JPG_DEFAULT_HEADER_PART2_LENGTH);
|
|
dst += SPCA50X_JPG_DEFAULT_HEADER_PART2_LENGTH;
|
|
}
|
|
memcpy (dst, SPCA50xJPGDefaultHeaderPart3,
|
|
SPCA50X_JPG_DEFAULT_HEADER_PART3_LENGTH);
|
|
|
|
/* modify the image width, height */
|
|
*(dst + 8) = w & 0xFF; /* Image width low byte */
|
|
*(dst + 7) = w >> 8 & 0xFF; /* Image width high byte */
|
|
*(dst + 6) = h & 0xFF; /* Image height low byte */
|
|
*(dst + 5) = h >> 8 & 0xFF; /* Image height high byte */
|
|
|
|
/* set the format */
|
|
*(dst + 11) = format;
|
|
|
|
/* point to real JPG compress data start position and copy */
|
|
dst += SPCA50X_JPG_DEFAULT_HEADER_PART3_LENGTH;
|
|
|
|
for (i = 0; i < o_size; i++) {
|
|
if (dst - start >= *size) return GP_ERROR;
|
|
value = *(src + i) & 0xFF;
|
|
*(dst) = value;
|
|
dst++;
|
|
|
|
if (value == 0xFF && !omit_escape) {
|
|
if (dst - start >= *size) return GP_ERROR;
|
|
*(dst) = 0x00;
|
|
dst++;
|
|
}
|
|
}
|
|
if (dst + 2 - start >= *size) return GP_ERROR;
|
|
/* Add end of image marker */
|
|
*(dst++) = 0xFF;
|
|
*(dst++) = 0xD9;
|
|
|
|
*size = dst - start;
|
|
return GP_OK;
|
|
}
|