~ubuntu-branches/ubuntu/saucy/libgphoto2/saucy-proposed

« back to all changes in this revision

Viewing changes to camlibs/canon/canon.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-07-31 07:00:09 UTC
  • mfrom: (1.4.4)
  • Revision ID: package-import@ubuntu.com-20130731070009-enrbvg3hry64cxl1
Tags: 2.5.2-0ubuntu1
* New upstream release.
* Drop 01-increase_max_entries.patch, 02-libusbx_no_debug.patch,
  03-libusbx-fixes.patch: fixed upstream.
* Add libxml2-dev build dependency for new optional features.
* ABI changes: libgphoto2-2 → libgphoto2-6,
  libgphoto2-port0 → libgphoto2-port10
* debian/libgphoto2-dev-doc.install: Adjust to changed HTML API doc folder
  name.
* debian/libgphoto2-port10.install: Adjust for changed libgphoto-port ABI.

Show diffs side-by-side

added added

removed removed

Lines of Context:
212
212
        {"Canon:EOS 300D (normal mode)", CANON_CLASS_4, 0x04A9, 0x3084, CAP_SUP, SL_MOVIE_SMALL, SL_THUMB, SL_PICTURE, NULL},
213
213
        {"Canon:EOS Digital Rebel (normal mode)",CANON_CLASS_4, 0x04A9, 0x3084, CAP_SUP, SL_MOVIE_SMALL, SL_THUMB, SL_PICTURE, NULL},
214
214
        {"Canon:EOS Kiss Digital (normal mode)",CANON_CLASS_4,  0x04A9, 0x3084, CAP_SUP, SL_MOVIE_SMALL, SL_THUMB, SL_PICTURE, NULL},
 
215
 
215
216
#if 0
216
217
        /* PS G5 uses the same ProductID for PTP and Canon, with protocol autodetection */
217
 
        /* Use PTP driver, as this driver had broken reports - Marcus */
 
218
        /* Use PTP driver, as this driver had broken reports - Marcus*/
218
219
        {"Canon:PowerShot G5 (normal mode)", CANON_CLASS_5,     0x04A9, 0x3085, CAP_SUP, SL_MOVIE_LARGE, SL_THUMB, SL_PICTURE, NULL},
219
220
#endif
220
221
 
1333
1334
                        if ( is_image ( new_name ) ) {
1334
1335
                                /* Yup, we'll assume that this is the new image. */
1335
1336
                                GP_DEBUG ( "  Found our new image file" );
1336
 
                                strncpy ( path->name, new_name,
1337
 
                                          strlen ( new_name ) );
 
1337
                                strcpy ( path->name, new_name );
1338
1338
                                strcpy ( path->folder, canon2gphotopath ( camera, path->folder ) );
1339
1339
 
1340
1340
                                /* FIXME: Marcus: make it less large effort... */
1735
1735
                        status = canon_int_do_control_dialogue (camera,
1736
1736
                                                                CANON_USB_CONTROL_GET_PARAMS,
1737
1737
                                                                0x00, 0, &response, &len);
1738
 
                        
 
1738
                        if ( status != GP_OK )
 
1739
                                return status;
 
1740
 
1739
1741
                        if ( response == NULL )
1740
1742
                                return GP_ERROR_OS_FAILURE;
1741
1743
                        break;
2027
2029
 
2028
2030
 
2029
2031
/**
 
2032
 * canon_int_get_zoom
 
2033
 * @camera: camera to work with
 
2034
 * @zoom_level: pointer to hold returned zoom level - A40: 1..10; G1: 0..40 (pMaxOpticalZoomPos*4)
 
2035
 * @zoom_max: pointer to hold zoom upper bound
 
2036
 * @context: context for error reporting
 
2037
 *
 
2038
 * Gets the camera's zoom. Only tested for G1 via USB.
 
2039
 *
 
2040
 * Returns: gphoto2 error code
 
2041
 *
 
2042
 */
 
2043
int
 
2044
canon_int_get_zoom (Camera *camera,
 
2045
                    unsigned char *zoom_level,
 
2046
                    unsigned char *zoom_max,
 
2047
                    GPContext *context)
 
2048
{
 
2049
        unsigned char *msg = NULL;
 
2050
        unsigned int datalen = 0;
 
2051
        unsigned char payload[0x4c];
 
2052
        int payloadlen;
 
2053
        char desc[128];
 
2054
 
 
2055
        *zoom_level = 0;
 
2056
        *zoom_max = 0;
 
2057
        GP_DEBUG ("canon_int_get_zoom() called");
 
2058
 
 
2059
        payloadlen = canon_int_pack_control_subcmd( payload,
 
2060
                                                    CANON_USB_CONTROL_GET_ZOOM_POS,
 
2061
                                                    0, 0, desc );
 
2062
 
 
2063
        if ( camera->pl->md->model == CANON_CLASS_6 ) {
 
2064
                /* Newer protocol uses a different code, but with same
 
2065
                 * response. It also needs an extra zero byte at the
 
2066
                 * end. */
 
2067
                payload[payloadlen++] = 0;
 
2068
                msg = canon_usb_dialogue ( camera,
 
2069
                                           CANON_USB_FUNCTION_CONTROL_CAMERA_2,
 
2070
                                           &datalen, payload, payloadlen );
 
2071
        }
 
2072
        else
 
2073
                msg = canon_usb_dialogue ( camera,
 
2074
                                           CANON_USB_FUNCTION_CONTROL_CAMERA,
 
2075
                                           &datalen, payload, payloadlen );
 
2076
        if ( msg == NULL  && datalen != 0x1c) {
 
2077
                /* ERROR */
 
2078
                GP_DEBUG ("%s datalen=%x",
 
2079
                          desc, datalen);
 
2080
                return GP_ERROR_CORRUPTED_DATA;
 
2081
        }
 
2082
 
 
2083
        *zoom_level = msg[12];
 
2084
        *zoom_max = msg[14];
 
2085
 
 
2086
        msg = NULL;
 
2087
        datalen = 0;
 
2088
 
 
2089
        GP_DEBUG ("canon_int_get_zoom() finished successfully level=%d", *zoom_level);
 
2090
 
 
2091
        return GP_OK;
 
2092
}
 
2093
 
 
2094
 
 
2095
/**
2030
2096
 * canon_int_set_image_format
2031
2097
 * @camera: camera to work with
2032
2098
 * @res_byte1: byte 1 of the 3-byte image format code
2981
3047
{
2982
3048
        GP_DEBUG ("<CameraFileInfo>");
2983
3049
        GP_DEBUG ("  <CameraFileInfoFile>");
2984
 
        if ((info->file.fields & GP_FILE_INFO_NAME) != 0)
2985
 
                GP_DEBUG ("    Name:   %s", info->file.name);
2986
3050
        if ((info->file.fields & GP_FILE_INFO_TYPE) != 0)
2987
3051
                GP_DEBUG ("    Type:   %s", info->file.type);
2988
3052
        if ((info->file.fields & GP_FILE_INFO_SIZE) != 0)
3243
3307
                        /* OK, this directory entry has a name in it. */
3244
3308
 
3245
3309
                        if ((list_folders && is_dir) || (list_files && is_file)) {
 
3310
                                const char *filename = (char *)dirent_name;
3246
3311
 
3247
3312
                                /* we're going to fill out the info structure
3248
3313
                                   in this block */
3251
3316
                                /* we start with nothing and continously add stuff */
3252
3317
                                info.file.fields = GP_FILE_INFO_NONE;
3253
3318
 
3254
 
                                strncpy (info.file.name, (char *)dirent_name, sizeof (info.file.name));
3255
 
                                info.file.fields |= GP_FILE_INFO_NAME;
3256
 
 
3257
3319
                                info.file.mtime = dirent_time;
3258
3320
                                if (info.file.mtime != 0)
3259
3321
                                        info.file.fields |= GP_FILE_INFO_MTIME;
3264
3326
                                         */
3265
3327
 
3266
3328
                                        strncpy (info.file.type,
3267
 
                                                 filename2mimetype (info.file.name),
 
3329
                                                 filename2mimetype (filename),
3268
3330
                                                 sizeof (info.file.type));
3269
3331
                                        info.file.fields |= GP_FILE_INFO_TYPE;
3270
3332
 
3301
3363
                                         * because we have additional information.
3302
3364
                                         */
3303
3365
                                        if (!camera->pl->list_all_files
3304
 
                                            && !is_image (info.file.name)
3305
 
                                            && !is_movie (info.file.name)
3306
 
                                            && !is_audio (info.file.name)) {
 
3366
                                            && !is_image (filename)
 
3367
                                            && !is_movie (filename)
 
3368
                                            && !is_audio (filename)) {
3307
3369
                                                /* FIXME: Find associated main file and add it there */
3308
3370
                                                /* do nothing */
3309
3371
                                                GP_DEBUG ("Ignored %s/%s", folder,
3310
 
                                                          info.file.name);
 
3372
                                                          filename);
3311
3373
                                        } else {
3312
3374
                                                const char *thumbname;
3313
3375
 
3314
3376
                                                res = gp_filesystem_append (camera->fs, folder,
3315
 
                                                                      info.file.name, context);
 
3377
                                                                      filename, context);
3316
3378
                                                if (res != GP_OK) {
3317
3379
                                                        GP_DEBUG ("Could not gp_filesystem_append "
3318
3380
                                                                  "%s in folder %s: %s",
3319
 
                                                                  info.file.name, folder, gp_result_as_string (res));
 
3381
                                                                  filename, folder, gp_result_as_string (res));
3320
3382
                                                } else {
3321
3383
                                                        GP_DEBUG ("Added file %s/%s", folder,
3322
 
                                                                  info.file.name);
 
3384
                                                                  filename);
3323
3385
 
3324
3386
                                                        thumbname =
3325
3387
                                                                canon_int_filename2thumbname (camera,
3326
 
                                                                                              info.file.name);
 
3388
                                                                                              filename);
3327
3389
                                                        if (thumbname == NULL) {
3328
3390
                                                                /* no thumbnail */
3329
3391
                                                        } else {
3330
 
                                                                if ( is_cr2 ( info.file.name ) ) {
 
3392
                                                                if ( is_cr2 ( filename ) ) {
3331
3393
                                                                        /* We get the first part of the raw file as the thumbnail;
3332
3394
                                                                           this is (almost) a valid EXIF file. */
3333
3395
                                                                        info.preview.fields =
3347
3409
                                                        }
3348
3410
 
3349
3411
                                                        res = gp_filesystem_set_info_noop (camera->fs,
3350
 
                                                                                     folder, info,
 
3412
                                                                                     folder, filename, info,
3351
3413
                                                                                     context);
3352
3414
                                                        if (res != GP_OK) {
3353
3415
                                                                GP_DEBUG ("Could not gp_filesystem_set_info_noop() "
3354
3416
                                                                          "%s in folder %s: %s",
3355
 
                                                                          info.file.name, folder, gp_result_as_string (res));
 
3417
                                                                          filename, folder, gp_result_as_string (res));
3356
3418
                                                        }
3357
3419
                                                }
3358
3420
                                                GP_DEBUG ( "file \"%s\" has preview of MIME type \"%s\"",
3359
 
                                                           info.file.name, info.preview.type );
 
3421
                                                           filename, info.preview.type );
3360
3422
                                        }
3361
3423
                                }
3362
3424
                                /* Some cameras have ".." explicitly
3363
3425
                                 * at the end of each directory. We
3364
3426
                                 * will silently omit this from the
3365
3427
                                 * directory returned. */
3366
 
                                if ( is_dir && strcmp ( "..", info.file.name ) ) {
3367
 
                                        res = gp_list_append (list, info.file.name, NULL);
 
3428
                                if ( is_dir && strcmp ( "..", filename ) ) {
 
3429
                                        res = gp_list_append (list, filename, NULL);
3368
3430
                                        if (res != GP_OK)
3369
3431
                                                GP_DEBUG ("Could not gp_list_append "
3370
3432
                                                          "folder %s: %s",
3582
3644
 *
3583
3645
 */
3584
3646
int
3585
 
canon_int_put_file (Camera *camera, CameraFile *file, char *destname, char *destpath,
3586
 
                    GPContext *context)
 
3647
canon_int_put_file (Camera *camera, CameraFile *file, const char *filename,
 
3648
                    const char *destname, const char *destpath, GPContext *context)
3587
3649
{
3588
3650
        switch (camera->port->type) {
3589
3651
                case GP_PORT_USB:
3590
 
                        return canon_usb_put_file (camera, file, destname, destpath,
 
3652
                        return canon_usb_put_file (camera, file, filename, destname, destpath,
3591
3653
                                                      context);
3592
3654
                        break;
3593
3655
                case GP_PORT_SERIAL:
3594
 
                        return canon_serial_put_file (camera, file, destname, destpath,
 
3656
                        return canon_serial_put_file (camera, file, filename, destname, destpath,
3595
3657
                                                      context);
3596
3658
                        break;
3597
3659
                GP_PORT_DEFAULT
3615
3677
        return GP_ERROR;
3616
3678
}
3617
3679
 
 
3680
/* NOTE:
 
3681
 * This function should actually not be necessary, as
 
3682
 * canon_int_list_directory preps the filesystem info backing store with
 
3683
 * all the CameraFileInfos it needs.
 
3684
 * It might never be called.
 
3685
 */
 
3686
int
 
3687
canon_int_get_info_func (Camera *camera, const char *folder,
 
3688
                const char *filename, CameraFileInfo *info,
 
3689
                GPContext *context)
 
3690
{
 
3691
        /* FIXME: big copy and paste mess from canon_int_list_directory */
 
3692
        int res;
 
3693
        unsigned int dirents_length;
 
3694
        unsigned char *dirent_data = NULL;
 
3695
        unsigned char *end_of_data, *temp_ch, *pos;
 
3696
        const char *canonfolder = gphoto2canonpath (camera, folder, context);
 
3697
 
 
3698
        GP_DEBUG ("BEGIN canon_int_get_info_func() folder '%s' aka '%s' filename %s", folder, canonfolder, filename);
 
3699
 
 
3700
        if ( canonfolder == NULL ) {
 
3701
                GP_DEBUG ( "Error: canon_int_get_info_func called with null name for camera folder" );
 
3702
                return GP_ERROR;
 
3703
        }
 
3704
 
 
3705
        /* Fetch all directory entries from the camera */
 
3706
        switch (camera->port->type) {
 
3707
                case GP_PORT_USB:
 
3708
                        res = canon_usb_get_dirents (camera, &dirent_data, &dirents_length,
 
3709
                                                     canonfolder, context);
 
3710
                        break;
 
3711
                case GP_PORT_SERIAL:
 
3712
                        res = canon_serial_get_dirents (camera, &dirent_data, &dirents_length,
 
3713
                                                        canonfolder, context);
 
3714
                        break;
 
3715
                GP_PORT_DEFAULT
 
3716
        }
 
3717
        if (res != GP_OK)
 
3718
                return res;
 
3719
 
 
3720
        end_of_data = dirent_data + dirents_length;
 
3721
 
 
3722
        if (dirents_length < CANON_MINIMUM_DIRENT_SIZE) {
 
3723
                gp_context_error (context,
 
3724
                                  _("canon_int_get_info_func: ERROR: "
 
3725
                                    "initial message too short (%i < minimum %i)"),
 
3726
                                  dirents_length, CANON_MINIMUM_DIRENT_SIZE);
 
3727
                free (dirent_data);
 
3728
                dirent_data = NULL;
 
3729
                return GP_ERROR_CORRUPTED_DATA;
 
3730
        }
 
3731
 
 
3732
        /* The first data we have got here is the dirent for the
 
3733
         * directory we are reading. Skip over 10 bytes
 
3734
         * (2 for attributes, 4 date and 4 size) and then go find
 
3735
         * the end of the directory name so that we get to the next
 
3736
         * dirent which is actually the first one we are interested
 
3737
         * in
 
3738
         */
 
3739
        GP_DEBUG ("canon_int_get_info_func: Camera directory listing for directory '%s'",
 
3740
                  dirent_data + CANON_DIRENT_NAME);
 
3741
 
 
3742
        for (pos = dirent_data + CANON_DIRENT_NAME; pos < end_of_data && *pos != 0; pos++)
 
3743
                /* do nothing */ ;
 
3744
        if (pos == end_of_data || *pos != 0) {
 
3745
                gp_log (GP_LOG_ERROR, "canon_int_get_info_func",
 
3746
                                  "Reached end of packet while examining the first dirent");
 
3747
                free (dirent_data);
 
3748
                dirent_data = NULL;
 
3749
                return GP_ERROR_CORRUPTED_DATA;
 
3750
        }
 
3751
        pos++;                  /* skip NULL byte terminating directory name */
 
3752
 
 
3753
        /* we are now positioned at the first interesting dirent */
 
3754
 
 
3755
        /* This is the main loop, for every directory entry returned */
 
3756
        while (pos < end_of_data) {
 
3757
                int is_dir, is_file;
 
3758
                uint16_t dirent_attrs;  /* attributes of dirent */
 
3759
                uint32_t dirent_file_size;      /* size of dirent in octets */
 
3760
                uint32_t dirent_time;   /* time stamp of dirent (Unix Epoch) */
 
3761
                uint8_t *dirent_name;   /* name of dirent */
 
3762
                size_t dirent_name_len; /* length of dirent_name */
 
3763
                size_t dirent_ent_size; /* size of dirent in octets */
 
3764
                uint32_t tmp_time;
 
3765
                time_t date;
 
3766
                struct tm *tm;
 
3767
 
 
3768
                dirent_attrs = le16atoh (pos + CANON_DIRENT_ATTRS);
 
3769
                dirent_file_size = le32atoh (pos + CANON_DIRENT_SIZE);
 
3770
                dirent_name = pos + CANON_DIRENT_NAME;
 
3771
 
 
3772
                /* see canon_int_set_time() for timezone handling */
 
3773
                tmp_time = le32atoh (pos + CANON_DIRENT_TIME);
 
3774
                if (tmp_time != 0) {
 
3775
                        /* FIXME: I just want the tm_gmtoff/timezone info */
 
3776
                        date = time(NULL);
 
3777
                        tm   = localtime (&date);
 
3778
#ifdef HAVE_TM_GMTOFF
 
3779
                        dirent_time = tmp_time - tm->tm_gmtoff;
 
3780
                        GP_DEBUG ("canon_int_get_info_func: converted %ld to UTC %ld (tm_gmtoff is %ld)",
 
3781
                                (long)tmp_time, (long)dirent_time, (long)tm->tm_gmtoff);
 
3782
#else
 
3783
                        dirent_time = tmp_time + timezone;
 
3784
                        GP_DEBUG ("canon_int_get_info_func: converted %ld to UTC %ld (timezone is %ld)",
 
3785
                                (long)tmp_time, (long)dirent_time, (long)timezone);
 
3786
#endif
 
3787
                } else {
 
3788
                        dirent_time = tmp_time;
 
3789
                }
 
3790
 
 
3791
                is_dir = ((dirent_attrs & CANON_ATTR_NON_RECURS_ENT_DIR) != 0)
 
3792
                        || ((dirent_attrs & CANON_ATTR_RECURS_ENT_DIR) != 0);
 
3793
                is_file = !is_dir;
 
3794
 
 
3795
                gp_log (GP_LOG_DATA, "canon/canon.c",
 
3796
                        "canon_int_get_info_func: "
 
3797
                        "reading dirent at position %li of %li (0x%lx of 0x%lx)",
 
3798
                        (long)(pos - dirent_data), (long)(end_of_data - dirent_data),
 
3799
                        (long)(pos - dirent_data), (long)(end_of_data - dirent_data) );
 
3800
 
 
3801
                if (pos + CANON_MINIMUM_DIRENT_SIZE > end_of_data) {
 
3802
                        if (camera->port->type == GP_PORT_SERIAL) {
 
3803
                                /* check to see if it is only NULL bytes left,
 
3804
                                 * that is not an error for serial cameras
 
3805
                                 * (at least the A50 adds five zero bytes at the end)
 
3806
                                 */
 
3807
                                for (temp_ch = pos; (temp_ch < end_of_data) && (!*temp_ch); temp_ch++) ;        /* do nothing */
 
3808
 
 
3809
                                if (temp_ch == end_of_data) {
 
3810
                                        GP_DEBUG ("canon_int_get_info_func: "
 
3811
                                                  "the last %li bytes were all 0 - ignoring.",
 
3812
                                                  (long)(temp_ch - pos));
 
3813
                                        break;
 
3814
                                } else {
 
3815
                                        GP_DEBUG ("canon_int_get_info_func: "
 
3816
                                                  "byte[%li=0x%lx] == %i=0x%x", (long)(temp_ch - pos),
 
3817
                                                  (long)(temp_ch - pos), *temp_ch, *temp_ch);
 
3818
                                        GP_DEBUG ("canon_int_get_info_func: "
 
3819
                                                  "pos is %p, end_of_data is %p, temp_ch is %p - diff is 0x%lx",
 
3820
                                                  pos, end_of_data, temp_ch, (long)(temp_ch - pos));
 
3821
                                }
 
3822
                        }
 
3823
                        GP_DEBUG ("canon_int_get_info_func: "
 
3824
                                  "dirent at position %li=0x%lx of %li=0x%lx is too small, "
 
3825
                                  "minimum dirent is %i bytes",
 
3826
                                  (long)(pos - dirent_data), (long)(pos - dirent_data),
 
3827
                                  (long)(end_of_data - dirent_data), (long)(end_of_data - dirent_data),
 
3828
                                  CANON_MINIMUM_DIRENT_SIZE);
 
3829
                        gp_log (GP_LOG_ERROR,"canon_int_get_info_func", "truncated directory entry encountered");
 
3830
                        free (dirent_data);
 
3831
                        dirent_data = NULL;
 
3832
                        return GP_ERROR_CORRUPTED_DATA;
 
3833
                }
 
3834
 
 
3835
                /* Check end of this dirent, 10 is to skip over
 
3836
                 * 2    attributes + 0x00
 
3837
                 * 4    file size
 
3838
                 * 4    file date (UNIX localtime)
 
3839
                 * to where the direntry name begins.
 
3840
                 */
 
3841
                for (temp_ch = dirent_name; temp_ch < end_of_data && *temp_ch != 0;
 
3842
                     temp_ch++) ;
 
3843
 
 
3844
                if (temp_ch == end_of_data || *temp_ch != 0) {
 
3845
                        GP_DEBUG ("canon_int_get_info_func: "
 
3846
                                  "dirent at position %li of %li has invalid name in it."
 
3847
                                  "bailing out with what we've got.",
 
3848
                                  (long)(pos - dirent_data),
 
3849
                                  (long)(end_of_data - dirent_data));
 
3850
                        break;
 
3851
                }
 
3852
                dirent_name_len = strlen ((char *)dirent_name);
 
3853
                dirent_ent_size = CANON_MINIMUM_DIRENT_SIZE + dirent_name_len;
 
3854
 
 
3855
                /* check that length of name in this dirent is not of unreasonable size.
 
3856
                 * 256 was picked out of the blue
 
3857
                 */
 
3858
                if (dirent_name_len > 256) {
 
3859
                        GP_DEBUG ("canon_int_get_info_func: "
 
3860
                                  "the name in dirent at position %li of %li is too long. (%li bytes)."
 
3861
                                  "bailing out with what we've got.",
 
3862
                                  (long)(pos - dirent_data), (long)(end_of_data - dirent_data),
 
3863
                                  (long)dirent_name_len);
 
3864
                        break;
 
3865
                }
 
3866
 
 
3867
                /* 10 bytes of attributes, size and date, a name and a NULL terminating byte */
 
3868
                /* don't use GP_DEBUG since we log this with GP_LOG_DATA */
 
3869
                gp_log (GP_LOG_DATA, "canon/canon.c",
 
3870
                        "canon_int_get_info_func: dirent determined to be %li=0x%lx bytes :",
 
3871
                        (long)dirent_ent_size, (long)dirent_ent_size);
 
3872
                gp_log_data ("canon", (char *)pos, dirent_ent_size);
 
3873
                if (dirent_name_len) {
 
3874
                        /* OK, this directory entry has a name in it. */
 
3875
 
 
3876
                        if (!strcmp(filename, (char*)dirent_name)) {
 
3877
                                /* we're going to fill out the info structure
 
3878
                                   in this block */
 
3879
 
 
3880
                                /* We start with nothing and continously add stuff */
 
3881
                                info->file.fields = GP_FILE_INFO_NONE;
 
3882
 
 
3883
                                info->file.mtime = dirent_time;
 
3884
                                if (info->file.mtime != 0)
 
3885
                                        info->file.fields |= GP_FILE_INFO_MTIME;
 
3886
 
 
3887
                                if (is_file) {
 
3888
                                        /* determine file type based on file name
 
3889
                                         * this stuff only makes sense for files, not for folders
 
3890
                                         */
 
3891
 
 
3892
                                        strncpy (info->file.type,
 
3893
                                                 filename2mimetype (filename),
 
3894
                                                 sizeof (info->file.type));
 
3895
                                        info->file.fields |= GP_FILE_INFO_TYPE;
 
3896
 
 
3897
                                        if ((dirent_attrs & CANON_ATTR_DOWNLOADED) == 0)
 
3898
                                                info->file.status = GP_FILE_STATUS_DOWNLOADED;
 
3899
                                        else
 
3900
                                                info->file.status =
 
3901
                                                        GP_FILE_STATUS_NOT_DOWNLOADED;
 
3902
                                        info->file.fields |= GP_FILE_INFO_STATUS;
 
3903
 
 
3904
                                        /* the size is located at offset 2 and is 4
 
3905
                                         * bytes long, re-order little/big endian */
 
3906
                                        info->file.size = dirent_file_size;
 
3907
                                        info->file.fields |= GP_FILE_INFO_SIZE;
 
3908
 
 
3909
                                        /* file access modes */
 
3910
                                        if ((dirent_attrs & CANON_ATTR_WRITE_PROTECTED) == 0)
 
3911
                                                info->file.permissions =
 
3912
                                                        GP_FILE_PERM_READ |
 
3913
                                                        GP_FILE_PERM_DELETE;
 
3914
                                        else
 
3915
                                                info->file.permissions = GP_FILE_PERM_READ;
 
3916
                                        info->file.fields |= GP_FILE_INFO_PERMISSIONS;
 
3917
                                }
 
3918
 
 
3919
                                /* print dirent as text */
 
3920
                                GP_DEBUG ("Raw info: name=%s is_dir=%i, is_file=%i, attrs=0x%x",
 
3921
                                          dirent_name, is_dir, is_file, dirent_attrs);
 
3922
                                debug_fileinfo (info);
 
3923
 
 
3924
                                if (is_file) {
 
3925
                                        /*
 
3926
                                         * Append directly to the filesystem instead of to the list,
 
3927
                                         * because we have additional information.
 
3928
                                         */
 
3929
                                        if (!camera->pl->list_all_files
 
3930
                                            && !is_image (filename)
 
3931
                                            && !is_movie (filename)
 
3932
                                            && !is_audio (filename)) {
 
3933
                                                /* FIXME: Find associated main file and add it there */
 
3934
                                                /* do nothing */
 
3935
                                                GP_DEBUG ("Ignored %s/%s", folder, filename);
 
3936
                                        } else {
 
3937
                                                const char *thumbname;
 
3938
 
 
3939
 
 
3940
                                                thumbname = canon_int_filename2thumbname (camera,
 
3941
                                                                                              filename);
 
3942
                                                if (thumbname == NULL) {
 
3943
                                                        /* no thumbnail */
 
3944
                                                } else {
 
3945
                                                        if ( is_cr2 ( filename ) ) {
 
3946
                                                                /* We get the first part of the raw file as the thumbnail;
 
3947
                                                                   this is (almost) a valid EXIF file. */
 
3948
                                                                info->preview.fields = GP_FILE_INFO_TYPE;
 
3949
                                                                strcpy (info->preview.type, GP_MIME_EXIF);
 
3950
                                                        } else {
 
3951
                                                                /* Older Canon cams have JPEG thumbs */
 
3952
                                                                info->preview.fields = GP_FILE_INFO_TYPE;
 
3953
                                                                strcpy (info->preview.type, GP_MIME_JPEG);
 
3954
                                                        }
 
3955
                                                }
 
3956
                                                GP_DEBUG ( "file \"%s\" has preview of MIME type \"%s\"",
 
3957
                                                           filename, info->preview.type );
 
3958
                                        }
 
3959
                                }
 
3960
                                /* found ... leave loop */
 
3961
                                break;
 
3962
                        }
 
3963
                }
 
3964
 
 
3965
                /* make 'pos' point to next dirent in packet.
 
3966
                 * first we skip 10 bytes of attribute, size and date,
 
3967
                 * then we skip the name plus 1 for the NULL
 
3968
                 * termination bytes.
 
3969
                 */
 
3970
                pos += dirent_ent_size;
 
3971
        }
 
3972
        free (dirent_data);
 
3973
        dirent_data = NULL;
 
3974
 
 
3975
        GP_DEBUG ("END canon_int_get_info_func() folder '%s' aka '%s' fn '%s'", folder, canonfolder, filename);
 
3976
 
 
3977
        return GP_OK;
 
3978
}
 
3979
 
3618
3980
 
3619
3981
/**
3620
3982
 * canon_int_extract_jpeg_thumb:
3700
4062
                 * JPEG thumbnail and just fetch the thumbnail to get
3701
4063
                 * the EXIF data. */
3702
4064
                int ifd0_offset, ifd1_offset, n_tags;
3703
 
                int jpeg_offset = -1, jpeg_size = -1, i;
 
4065
                int jpeg_offset = -1, jpeg_size = -1;
3704
4066
 
3705
4067
                GP_DEBUG ( "canon_int_extract_jpeg_thumb: this is from a CR2 file.");
3706
4068
                dump_hex ( stderr, data, 32 );