diff options
author | Hans de Goede <hdegoede@redhat.com> | 2010-04-28 13:06:59 +0000 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2010-04-28 13:06:59 +0000 |
commit | 58982576a6abca35332b809f461be6b15533d679 (patch) | |
tree | f6f01b788609635fc71e16e3c92b25c3cd3ee00a /camlibs/st2205 | |
parent | 9b7faba675347ba24aec4aca7a7485c53fbd4695 (diff) | |
download | libgphoto2-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.c | 128 | ||||
-rw-r--r-- | camlibs/st2205/st2205.c | 29 | ||||
-rw-r--r-- | camlibs/st2205/st2205.h | 13 |
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; |