Skip to content

Commit

Permalink
Add support for QuickTake 100/150
Browse files Browse the repository at this point in the history
- Summary
- Get/Set configuration
- Get preview
- Get PPM files
- Get raw files (QTK format)

Serial protocol reference: https://www.colino.net/wordpress/en/archives/2023/10/29/the-apple-quicktake-100-serial-communication-protocol/
QTKT / QTKN decoding algorithms from dcraw (GPL licensed).
  • Loading branch information
colinleroy committed Nov 16, 2023
1 parent 57de6e2 commit 22e5463
Show file tree
Hide file tree
Showing 12 changed files with 1,544 additions and 0 deletions.
3 changes: 3 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ scanner.
Hans de Goede <[email protected]>
ST2205 Picture Frame support (and usbdiskdirect port driver).

Colin Leroy-Mira <[email protected]>
Apple QuickTake 1x0 driver.

=========================================================================
git migration authors

Expand Down
1 change: 1 addition & 0 deletions camlibs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ include pccam600/Makefile-files
include pentax/Makefile-files
include polaroid/Makefile-files
include ptp2/Makefile-files
include quicktake1x0/Makefile-files
include ricoh/Makefile-files
include samsung/Makefile-files
include sierra/Makefile-files
Expand Down
20 changes: 20 additions & 0 deletions camlibs/quicktake1x0/Makefile-files
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- Makefile-automake -*-

#EXTRA_DIST += %reldir%/ChangeLog


EXTRA_LTLIBRARIES += quicktake1x0.la

quicktake1x0_la_SOURCES =
quicktake1x0_la_SOURCES += %reldir%/quicktake1x0.c
quicktake1x0_la_SOURCES += %reldir%/qtk-thumbnail-decoder.c
quicktake1x0_la_SOURCES += %reldir%/qtkt-decoder.c
quicktake1x0_la_SOURCES += %reldir%/qtkn-decoder.c
quicktake1x0_la_SOURCES += %reldir%/qtk-helpers.c
quicktake1x0_la_SOURCES += %reldir%/quicktake1x0.h

quicktake1x0_la_CFLAGS = $(camlib_cflags)
quicktake1x0_la_CPPFLAGS = $(camlib_cppflags)
quicktake1x0_la_DEPENDENCIES = $(camlib_dependencies)
quicktake1x0_la_LDFLAGS = $(camlib_ldflags)
quicktake1x0_la_LIBADD = $(camlib_libadd)
106 changes: 106 additions & 0 deletions camlibs/quicktake1x0/qtk-helpers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* qtk-helpers.c
*
Copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net
* Copyright 2023, Colin Leroy-Mira <[email protected]>
*
* getbithuff() heavily inspired from dcraw.c.
*
* 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 "quicktake1x0.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <gphoto2/gphoto2-library.h>
#include <libgphoto2/bayer.h>

/* Write a basic .qtk header. This is imperfect and may not allow to open the
* raw files we generate with the official, vintage Quicktake software, but it
* is enough for dcraw to open and convert it.
*/
void
qtk_raw_header(unsigned char *data, const char *pic_format)
{
char hdr[] = {0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x04,0x00,0x00,0x73,0xE4,0x00,0x01};

memcpy(hdr, pic_format, 4);
memcpy(data, hdr, sizeof hdr);
}

char *qtk_ppm_header(int width, int height) {
char *header = malloc(128);
if (header == NULL)
return NULL;

snprintf(header, 127,
"P6\n%d %d\n%d\n",
width, height, 255);

return header;
}

int qtk_ppm_size(int width, int height) {
char *header;
int len;

header = qtk_ppm_header(width, height);
if (header == NULL) {
return GP_ERROR_NO_MEMORY;
}

len = (width * height * 3) + strlen(header);
free(header);

return len;
}

unsigned char getbithuff (int nbits, unsigned char **raw, ushort *huff)
{
static unsigned bitbuf = 0;
static int vbits = 0;
unsigned char c;
int h;
unsigned char *ptr;

if (nbits == -1) {
bitbuf = 0;
vbits = 0;
return 0;
}

ptr = *raw;
if (vbits < nbits) {
c = *ptr;
ptr++; (*raw)++;
bitbuf = (bitbuf << 8) + c;
vbits += 8;
}
c = bitbuf << (32-vbits) >> (32-nbits);

if (!huff)
vbits -= nbits;
else {
h = huff[c];
vbits -= h >> 8;
c = (unsigned char) h;
}

return c;
}
70 changes: 70 additions & 0 deletions camlibs/quicktake1x0/qtk-thumbnail-decoder.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* qtkt-decoder.c
*
Copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net
* Copyright 2023, Colin Leroy-Mira <[email protected]>
*
* QTKT decoder heavily inspired from dcraw.c.
*
* 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 "quicktake1x0.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <gphoto2/gphoto2-library.h>

int qtk_thumbnail_decode(unsigned char *raw, unsigned char **out) {
int s, v, p1, p2, r, g, b, len;
char *header;
unsigned char *ptr;

header = qtk_ppm_header(QT1X0_THUMB_WIDTH, QT1X0_THUMB_HEIGHT);

len = qtk_ppm_size(QT1X0_THUMB_WIDTH, QT1X0_THUMB_HEIGHT);
*out = ptr = calloc(1, len);
if (ptr == NULL) {
free(header);
return GP_ERROR_NO_MEMORY;
}

strcpy((char *)ptr, header);
ptr += strlen(header);
free(header);

for (s = 0; s < QT1X0_THUMB_SIZE; s++) {
v = raw[s];

p1 = ((v >> 4) & 0b00001111) << 4;
p2 = ((v >> 0) & 0b00001111) << 4;

/* FIXME do color thumbnails */
r = g = b = p1;
*ptr++ = r;
*ptr++ = g;
*ptr++ = b;

r = g = b = p2;
*ptr++ = r;
*ptr++ = g;
*ptr++ = b;
}

return GP_OK;
}
Loading

0 comments on commit 22e5463

Please sign in to comment.