Files
libgphoto2/camlibs/clicksmart310/clicksmart.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

284 lines
7.5 KiB
C

/* clicksmart.c
*
* part of libgphoto2/camlibs/clicksmart310
*
* Copyright (C) 2006 Theodore Kilgore <kilgota@auburn.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include <gphoto2/gphoto2.h>
#include <gphoto2/gphoto2-port.h>
#include "clicksmart.h"
#include "spca50x-jpeg-header.h"
#define GP_MODULE "clicksmart310"
#define CS_INIT 0x8000
#define CS_INIT2 0xd41
#define CS_NUM_PICS 0xd40
#define CS_CH_READY 0xd00
#define CS_CH_CLEAR 0xd05
#define CS_READCLOSE 0x8303
static int
CLICKSMART_READ (GPPort *port, int index, char *data)
{
gp_port_usb_msg_interface_read(port, 0, 0, index, data, 1);
return GP_OK;
}
static int
CLICKSMART_READ_STATUS (GPPort *port, char *data)
{
return gp_port_usb_msg_interface_read(port, 0, 0, CS_CH_READY, data, 1);
}
int clicksmart_init (GPPort *port, CameraPrivateLibrary *priv)
{
int i, cat_size;
int full_reads;
int short_read;
unsigned char *temp_catalog;
unsigned char *buffer;
char c = 0;
GP_DEBUG("Running clicksmart_init\n");
CLICKSMART_READ(port, CS_INIT, &c);
/* We are supposed to get a response of 0x44 ???*/
CLICKSMART_READ(port, CS_INIT2, &c);
CLICKSMART_READ(port, CS_NUM_PICS, &c);
priv->num_pics = (unsigned)c;
full_reads = (unsigned)c/2;
short_read = (unsigned)c%2;
cat_size = (unsigned)c*0x10;
temp_catalog = malloc(cat_size);
if (!temp_catalog)
return GP_ERROR_NO_MEMORY;
memset (temp_catalog, 0, cat_size);
/* now we need to get and put away the catalog data. */
CLICKSMART_READ_STATUS (port, &c);
gp_port_usb_msg_interface_write(port, 6, 0, 9, NULL, 0);
while (c != 1) {
int r;
if ((r = CLICKSMART_READ_STATUS (port, &c)) < GP_OK)
return r;
}
buffer = malloc(0x200);
if (!buffer) {
free (temp_catalog);
return GP_ERROR_NO_MEMORY;
}
/*
* The catalog data is downloaded in reverse order, which needs to be
* straightened out.
*/
for (i=0; i < full_reads; i++) {
memset (buffer, 0, 0x200);
gp_port_read(port, (char *)buffer, 0x200);
memcpy (temp_catalog + cat_size - (2*i+1)*0x10, buffer, 0x10);
memcpy (temp_catalog + cat_size - (2*i+2)*0x10, buffer+0x100,
0x10);
}
if (short_read) {
memset (buffer, 0, 0x200);
gp_port_read(port, (char *)buffer, 0x100);
memcpy (temp_catalog, buffer, 0x10);
}
priv->catalog = temp_catalog;
clicksmart_reset(port);
free (buffer);
GP_DEBUG("Leaving clicksmart_init\n");
return GP_OK;
}
int clicksmart_get_res_setting (CameraPrivateLibrary *priv, int n)
{
GP_DEBUG("running clicksmart_get_res_setting for picture %i\n", n+1);
/*
* QCIF (176x144) returns 1, or if the entry is a clip frame, then 3
* and CIF (352x288) returns 0.
*/
return priv->catalog[16*n];
}
int
clicksmart_read_pic_data (CameraPrivateLibrary *priv, GPPort *port,
unsigned char **data, int n)
{
unsigned int offset=0;
char c;
unsigned int size = 0;
unsigned int remainder = 0;
GP_DEBUG("running clicksmart_read_picture_data for picture %i\n", n+1);
CLICKSMART_READ_STATUS (port, &c);
GP_DEBUG("ClickSmart Read Status at beginning %d\n", c);
gp_port_usb_msg_interface_write(port, 6, 0x1fff - n, 1, NULL, 0);
c = 0;
while (c != 1) {
int r;
if ((r = CLICKSMART_READ_STATUS (port, &c)) < GP_OK)
return r;
}
/* Get the size of the data and calculate the size to download, which
* is the next multiple of 0x100. Only for the hi-res photos is the
* true data size actually given.
*/
size=(priv->catalog[16*n + 12] * 0x100)+(priv->catalog[16*n + 11]);
if (size == 0) /* for lo-res photos the above calculation gives 0 */
size = (priv->catalog[16*n + 5] * 0x100);
if (size == 0) /* this means data corruption */
return GP_ERROR;
remainder = size%0x200;
GP_DEBUG("size: %x, remainder: %x\n", size, remainder);
*data = calloc(size + 0x100,1);
if (!*data) return GP_ERROR;
/* Download the data */
while (offset < size-remainder) {
GP_DEBUG("offset: %x\n", offset);
if (gp_port_read(port, (char *)*data + offset, 0x200) < GP_OK)
break;
offset = offset + 0x200;
}
remainder=((remainder+0xff)/0x100)*0x100;
GP_DEBUG("Second remainder: %x\n", remainder);
if (remainder)
gp_port_read(port, (char *)*data + offset, remainder);
gp_port_usb_msg_interface_read(port, 0, 0, CS_READCLOSE, &c, 1);
gp_port_usb_msg_interface_write(port, 0, 2, CS_CH_READY, NULL, 0);
/*
* For lo-res photos the camera does not tell us the true size, but
* when the data has ended the excess bytes downloaded are all
* 00. The photo processing works better if these are suppressed.
*/
if (priv->catalog[16*n]) {
while ((size > 1) && (*data)[size-1] == 0)
size--;
}
return size;
}
int
clicksmart_delete_all_pics (GPPort *port)
{
gp_port_usb_msg_interface_write(port, 0, 2, CS_CH_READY, NULL, 0);
gp_port_usb_msg_interface_write(port, 2, 0, 5, NULL, 0);
return GP_OK;
}
int
clicksmart_reset (GPPort *port)
{
char c;
/* Release current register */
CLICKSMART_READ (port, CS_READCLOSE, &c);
gp_port_usb_msg_interface_write(port, 0, 2, CS_CH_READY, NULL, 0);
CLICKSMART_READ (port, CS_CH_CLEAR, &c);
CLICKSMART_READ (port, CS_CH_CLEAR, &c);
return GP_OK;
}
/* create_jpeg_from_data adapted from camlibs/spca50x */
int create_jpeg_from_data (unsigned char * dst, unsigned char * src,
int qIndex, int w, int h, unsigned char format,
int o_size, int *size,
int omit_huffman_table, int omit_escape)
{
int i = 0;
unsigned char *start;
unsigned char value;
start = dst;
/* copy the header from the template */
memcpy (dst, SPCA50xJPGDefaultHeaderPart1,
SPCA50X_JPG_DEFAULT_HEADER_PART1_LENGTH);
/* modify quantization table */
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;
}