summaryrefslogtreecommitdiff
path: root/camlibs/st2205
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2010-04-28 13:06:59 +0000
committerHans de Goede <hdegoede@redhat.com>2010-04-28 13:06:59 +0000
commit58982576a6abca35332b809f461be6b15533d679 (patch)
treef6f01b788609635fc71e16e3c92b25c3cd3ee00a /camlibs/st2205
parent9b7faba675347ba24aec4aca7a7485c53fbd4695 (diff)
downloadlibgphoto2-58982576a6abca35332b809f461be6b15533d679.tar.gz
st2205: Add support for 320x240 frames
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@13037 67ed7778-7388-44ab-90cf-0a291f65f57c
Diffstat (limited to 'camlibs/st2205')
-rw-r--r--camlibs/st2205/library.c128
-rw-r--r--camlibs/st2205/st2205.c29
-rw-r--r--camlibs/st2205/st2205.h13
3 files changed, 161 insertions, 9 deletions
diff --git a/camlibs/st2205/library.c b/camlibs/st2205/library.c
index f86a662be..59a9ca20a 100644
--- a/camlibs/st2205/library.c
+++ b/camlibs/st2205/library.c
@@ -128,6 +128,50 @@ static int get_file_idx(CameraPrivateLibrary *pl, const char *folder,
return i;
}
+#ifdef HAVE_GD
+static void
+rotate90 (gdImagePtr src, gdImagePtr dest)
+{
+ int x, y;
+
+ for (y = 0; y < dest->sy; y++)
+ for (x = 0; x < dest->sx; x++)
+ dest->tpixels[y][x] =
+ src->tpixels[src->sy - x - 1][y];
+}
+
+static void
+rotate270 (gdImagePtr src, gdImagePtr dest)
+{
+ int x, y;
+
+ for (y = 0; y < dest->sy; y++)
+ for (x = 0; x < dest->sx; x++)
+ dest->tpixels[y][x] =
+ src->tpixels[x][src->sx - y - 1];
+}
+
+static int
+needs_rotation (Camera *camera)
+{
+ int display_orientation, user_orientation = camera->pl->orientation;
+
+ if (camera->pl->width > camera->pl->height)
+ display_orientation = ORIENTATION_LANDSCAPE;
+ else
+ display_orientation = ORIENTATION_PORTRAIT;
+
+ if (user_orientation == ORIENTATION_AUTO) {
+ if (camera->pl->width == 240 && camera->pl->height == 320)
+ user_orientation = ORIENTATION_LANDSCAPE;
+ else
+ user_orientation = display_orientation;
+ }
+
+ return display_orientation != user_orientation;
+}
+#endif
+
static int
get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
CameraFileType type, CameraFile *file, void *data,
@@ -136,7 +180,7 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
Camera *camera = data;
int ret, idx, size;
#ifdef HAVE_GD
- gdImagePtr im;
+ gdImagePtr im, rotated;
void *gdpng;
#endif
@@ -171,6 +215,17 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
return ret;
}
+ if (needs_rotation (camera)) {
+ rotated = gdImageCreateTrueColor (im->sy, im->sx);
+ if (rotated == NULL) {
+ gdImageDestroy (im);
+ return GP_ERROR_NO_MEMORY;
+ }
+ rotate270 (im, rotated);
+ gdImageDestroy (im);
+ im = rotated;
+ }
+
gdpng = gdImagePngPtr(im, &size);
gdImageDestroy (im);
if (gdpng == NULL)
@@ -204,7 +259,7 @@ put_file_func (CameraFilesystem *fs, const char *folder, const char *name,
char *in, *out;
#endif
unsigned long filesize = 0;
- gdImagePtr im_out, im_in = NULL;
+ gdImagePtr rotated, im_out, im_in = NULL;
if (strcmp (folder, "/"))
return GP_ERROR_DIRECTORY_NOT_FOUND;
@@ -276,6 +331,18 @@ put_file_func (CameraFilesystem *fs, const char *folder, const char *name,
return GP_ERROR_BAD_PARAMETERS;
}
+ if (needs_rotation (camera)) {
+ rotated = gdImageCreateTrueColor (im_in->sy, im_in->sx);
+ if (rotated == NULL) {
+ gdImageDestroy (im_in);
+ free (out_name);
+ return GP_ERROR_NO_MEMORY;
+ }
+ rotate90 (im_in, rotated);
+ gdImageDestroy (im_in);
+ im_in = rotated;
+ }
+
im_out = gdImageCreateTrueColor(camera->pl->width, camera->pl->height);
if (im_out == NULL) {
gdImageDestroy (im_in);
@@ -429,6 +496,34 @@ static CameraFilesystemFuncs fsfuncs = {
.storage_info_func = storage_info_func
};
+static char *
+orientation_to_string (int orientation)
+{
+ switch (orientation) {
+ case ORIENTATION_AUTO:
+ return _("Auto");
+ case ORIENTATION_LANDSCAPE:
+ return _("Landscape");
+ case ORIENTATION_PORTRAIT:
+ return _("Portrait");
+ }
+ /* Never reached */
+ return NULL;
+}
+
+static int
+string_to_orientation (const char *str)
+{
+ if (strcmp (str, _("Auto")) == 0)
+ return ORIENTATION_AUTO;
+ else if (strcmp (str, _("Landscape")) == 0)
+ return ORIENTATION_LANDSCAPE;
+ else if (strcmp (str, _("Portrait")) == 0)
+ return ORIENTATION_PORTRAIT;
+ else
+ return GP_ERROR_NOT_SUPPORTED;
+}
+
static int
camera_get_config (Camera *camera, CameraWidget **window, GPContext *context)
{
@@ -444,6 +539,14 @@ camera_get_config (Camera *camera, CameraWidget **window, GPContext *context)
gp_widget_set_value (child, &camera->pl->syncdatetime);
gp_widget_append (*window, child);
+ gp_widget_new (GP_WIDGET_RADIO, _("Orientation"), &child);
+ gp_widget_add_choice (child, orientation_to_string (0));
+ gp_widget_add_choice (child, orientation_to_string (1));
+ gp_widget_add_choice (child, orientation_to_string (2));
+ gp_widget_set_value (child,
+ orientation_to_string (camera->pl->orientation));
+ gp_widget_append (*window, child);
+
return GP_OK;
}
@@ -460,6 +563,16 @@ camera_set_config (Camera *camera, CameraWidget *window, GPContext *context)
if (ret == GP_OK)
gp_widget_get_value (child, &camera->pl->syncdatetime);
+ ret = gp_widget_get_child_by_label (window, _("Orientation"), &child);
+ if (ret == GP_OK) {
+ char *value;
+ int orientation;
+ gp_widget_get_value (child, &value);
+ orientation = string_to_orientation (value);
+ if (orientation < 0) return orientation;
+ camera->pl->orientation = orientation;
+ }
+
return GP_OK;
}
@@ -471,7 +584,9 @@ camera_exit (Camera *camera, GPContext *context)
if (camera->pl != NULL) {
buf[0] = '0' + camera->pl->syncdatetime;
buf[1] = 0;
- gp_setting_set("st2205", "syncdatetime", buf);
+ gp_setting_set ("st2205", "syncdatetime", buf);
+ gp_setting_set ("st2205", "orientation", orientation_to_string
+ (camera->pl->orientation));
#ifdef HAVE_ICONV
if (camera->pl->cd != (iconv_t) -1)
iconv_close (camera->pl->cd);
@@ -514,6 +629,13 @@ camera_init (Camera *camera, GPContext *context)
else
camera->pl->syncdatetime = 1;
+ ret = gp_setting_get("st2205", "orientation", buf);
+ if (ret == GP_OK) {
+ ret = string_to_orientation (buf);
+ if (ret >= 0)
+ camera->pl->orientation = ret;
+ }
+
#ifdef HAVE_ICONV
curloc = nl_langinfo (CODESET);
if (!curloc)
diff --git a/camlibs/st2205/st2205.c b/camlibs/st2205/st2205.c
index b3af999c3..07fcdfc6f 100644
--- a/camlibs/st2205/st2205.c
+++ b/camlibs/st2205/st2205.c
@@ -219,7 +219,7 @@ st2205_detect_mem_size(Camera *camera)
if (ret)
return ret;
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < 3; i++) {
ret = st2205_read_block(camera,
(524288 / ST2205_BLOCK_SIZE) << i,
buf1);
@@ -801,6 +801,7 @@ st2205_init(Camera *camera)
uint16_t *lookup_src, *dest;
uint8_t *shuffle_src;
int x, y, i, j, shuffle_size, checksum, expected_checksum;
+ int is240x320 = 0;
const struct {
int width, height, no_tables, usable_tables;
unsigned char unknown3[8];
@@ -813,8 +814,7 @@ st2205_init(Camera *camera)
{ 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01 },
0x00025800 },
{ 120, 160, 7, 7,
- /* FIXME unknown3 needs to be verified */
- { 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01 },
+ { 0xff, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04 },
0x00030570 },
{ 96, 64, 7, 7,
{ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -844,6 +844,9 @@ st2205_init(Camera *camera)
return GP_ERROR_IO;
}
+ if (camera->pl->width == 240 && camera->pl->height == 320)
+ is240x320 = 1;
+
shuffle_size = (camera->pl->width / 8) * (camera->pl->height / 8);
if (shuffle_size > ST2205_SHUFFLE_SIZE) {
gp_log (GP_LOG_ERROR, "st2205",
@@ -912,6 +915,9 @@ st2205_init(Camera *camera)
if (camera->pl->width == shuffle_info[i].width &&
camera->pl->height == shuffle_info[i].height)
break;
+ if (is240x320 && shuffle_info[i].width == 120 &&
+ shuffle_info[i].height == 160)
+ break;
shuffle_src += (shuffle_info[i].width *
shuffle_info[i].height * 2 / 64) *
(shuffle_info[i].no_tables - 2);
@@ -940,6 +946,23 @@ st2205_init(Camera *camera)
}
checksum += camera->pl->shuffle[j][i].x;
checksum += camera->pl->shuffle[j][i].y;
+ if (is240x320) {
+ camera->pl->shuffle[j][i].x *= 2;
+ camera->pl->shuffle[j][i].y *= 2;
+ camera->pl->shuffle[j][i + 1].x =
+ camera->pl->shuffle[j][i].x + 8;
+ camera->pl->shuffle[j][i + 1].y =
+ camera->pl->shuffle[j][i].y;
+ camera->pl->shuffle[j][i + 2].x =
+ camera->pl->shuffle[j][i].x;
+ camera->pl->shuffle[j][i + 2].y =
+ camera->pl->shuffle[j][i].y + 8;
+ camera->pl->shuffle[j][i + 3].x =
+ camera->pl->shuffle[j][i].x + 8;
+ camera->pl->shuffle[j][i + 3].y =
+ camera->pl->shuffle[j][i].y + 8;
+ i += 3;
+ }
}
if (checksum != expected_checksum) {
diff --git a/camlibs/st2205/st2205.h b/camlibs/st2205/st2205.h
index a8bf40188..02c00d4f2 100644
--- a/camlibs/st2205/st2205.h
+++ b/camlibs/st2205/st2205.h
@@ -49,12 +49,18 @@
#define ST2205_V1_PICTURE_START 65536
#define ST2205_V2_PICTURE_START 8192
#define ST2205_LOOKUP_CHECKSUM 0x0016206f
-#define ST2205_SHUFFLE_SIZE (128 * 160 / 64)
+#define ST2205_SHUFFLE_SIZE (240 * 320 / 64)
#define ST2205_HEADER_MARKER 0xf5
/* The "FAT" cannot contain more then 510 entries */
#define ST2205_MAX_NO_FILES 510
#define ST2205_FILENAME_LENGTH 10
+enum {
+ ORIENTATION_AUTO,
+ ORIENTATION_LANDSCAPE,
+ ORIENTATION_PORTRAIT,
+};
+
/* We prefix all names with there idx in the FAT table, to make sure they are
all unique and don't change when files with the same name (after converting
to ascii and truncating) are added / deleted. */
@@ -62,8 +68,8 @@
snprintf(dest, sizeof(st2205_filename), "%04d-%s.png", (idx) + 1, name)
struct st2205_coord {
- uint8_t x;
- uint8_t y;
+ uint16_t x;
+ uint16_t y;
};
#define CHECK(result) {int r=(result); if (r<0) return (r);}
@@ -81,6 +87,7 @@ struct _CameraPrivateLibrary {
/* Driver configuration settings */
int syncdatetime;
+ int orientation;
/* Used by st2205.c / st2205_decode.c */
int width;