Files
libgphoto2/camlibs/spca50x/spca50x.c
axxel f41df32817 fix white-space and indentation inconsistencies (second round)
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).
2024-09-15 10:53:41 +02:00

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;
}