static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *user_data, GPContext *context) { Camera *camera = user_data; int n, len; char *data, *data_start; n = gp_filesystem_number(camera->fs, "/", filename, context); if (n<GP_OK) return n; len = ez200_get_picture_size (camera->port, n); GP_DEBUG("len = %i", len); data = (char *)malloc(len + HEADER_SIZE + 1); if (!data) return GP_ERROR_NO_MEMORY; data_start = data + (HEADER_SIZE - DATA_HEADER_SIZE); GP_DEBUG("data - data_start : %p %p : %lx",data, data_start, (long) (data_start - data)); ez200_read_picture_data (camera->port, data_start, len, n); ez200_read_picture_header (camera->port, data); switch (type) { case GP_FILE_TYPE_PREVIEW: case GP_FILE_TYPE_NORMAL: gp_file_set_mime_type (file, GP_MIME_JPEG); gp_file_set_data_and_size (file, data, len + HEADER_SIZE + 1); break; case GP_FILE_TYPE_RAW: gp_file_set_data_and_size (file, data, len); gp_file_set_mime_type (file, GP_MIME_RAW); gp_file_adjust_name_for_mime_type(file); break; default: return (GP_ERROR_NOT_SUPPORTED); } return GP_OK; }
static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *user_data, GPContext *context) { Camera *camera = user_data; /* The camera will always download the low-resolution pictures first, if any. * As those are compressed, they are not of fixed size. Unfortunately, the * compression method is not known. * For a high-resolution picture, the size is always the same. * Every picture file has a header, which is of length 0x98. The high- * resolution pictures are just Bayer data; their headers will be discarded. */ int i, j, k, n, num_lo_pics, num_hi_pics, w = 0, h = 0; unsigned char temp; unsigned char *data; unsigned char *p_data = NULL; unsigned char *output = NULL; int len; int header_len; char header[128]; unsigned char gtable[256]; k = gp_filesystem_number(camera->fs, "/", filename, context); num_lo_pics = aox_get_num_lo_pics(camera->pl->info); num_hi_pics = aox_get_num_hi_pics(camera->pl->info); GP_DEBUG("There are %i compressed photos\n", num_lo_pics); GP_DEBUG("There are %i hi-res photos\n", num_hi_pics); if ( (k < num_lo_pics) ) { n = k; w = 320; h = 240; } else { n = k - num_lo_pics; w = 640; h = 480; } len = aox_get_picture_size (camera->port, num_lo_pics, num_hi_pics, n, k); GP_DEBUG("len = %i\n", len); data = malloc(len); if (!data) { printf("Malloc failed\n"); return 0;} aox_read_picture_data (camera->port, (char *)data, len, n); switch (type) { case GP_FILE_TYPE_EXIF: free (data); return (GP_ERROR_FILE_EXISTS); case GP_FILE_TYPE_PREVIEW: case GP_FILE_TYPE_NORMAL: if (w == 320) { gp_file_detect_mime_type (file); /* Detected as "raw"*/ gp_file_set_data_and_size (file, (char *)data, len); gp_file_adjust_name_for_mime_type (file); break; } if (w == 640) { /* Stripping useless header */ p_data = data + 0x98; /* Picture is mirror-imaged.*/ for (i = 0; i < h; ++i) { for (j = 0 ; j < w/2; j++) { temp = p_data[w*i +j]; p_data[w*i +j] = p_data[w*i+ w -1 -j]; p_data[w*i + w - 1 - j] = temp; } } /* Not only this, but some columns are * interchanged, too. */ for (i = 0; i < w*h/4; i++) { temp = p_data[4*i +1]; p_data[4*i + 1] = p_data[4*i+2]; p_data[4*i+2] = temp; } /* And now create a ppm file, with our own header */ header_len = snprintf(header, 127, "P6\n" "# CREATOR: gphoto2, aox library\n" "%d %d\n" "255\n", w, h); output = malloc(3*w*h); if(!output) { free(output); return GP_ERROR_NO_MEMORY; } if (camera->pl->model == AOX_MODEL_DMAX) gp_bayer_decode (p_data, w, h, output, BAYER_TILE_RGGB); else gp_bayer_decode (p_data, w, h, output, BAYER_TILE_GRBG); /* gamma correction of .70 may not be optimal. */ gp_gamma_fill_table (gtable, .65); gp_gamma_correct_single (gtable, output, w * h); gp_file_set_mime_type (file, GP_MIME_PPM); gp_file_append (file, header, header_len); gp_file_append (file, (char *)output, 3*w*h); } free (data); free (output); return GP_OK; case GP_FILE_TYPE_RAW: gp_file_set_data_and_size (file, (char *)data, len); gp_file_set_mime_type (file, GP_MIME_RAW); gp_file_adjust_name_for_mime_type(file); break; default: free (data); return (GP_ERROR_NOT_SUPPORTED); } return GP_OK; }
static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *user_data, GPContext *context ) { Camera *camera = user_data; int num, width, height; uint8_t *data, *newdata; long int size; /* Retrieve the number of the photo on the camera */ if (strcmp(filename, RAM_IMAGE_TEMPLATE) == 0) /* Magic file name specifies magic image number */ num = RAM_IMAGE_NUM; else num = gp_filesystem_number(camera->fs, "/", filename, context); if (num < 0) return num; switch (type) { case GP_FILE_TYPE_NORMAL: data = Dimera_Get_Full_Image (num, &size, &width, &height, camera, context); if (!data) return GP_ERROR; gp_file_set_mime_type (file, GP_MIME_PPM); if (width == 640) gp_file_append (file, Dimera_finehdr, strlen(Dimera_finehdr)); else gp_file_append (file, Dimera_stdhdr, strlen(Dimera_stdhdr)); newdata = malloc(size*3); if (!newdata) return (GP_ERROR_NO_MEMORY); conversion_chuck (width, height, data, newdata); gp_file_append (file, newdata, size*3); free (newdata); free (data); break; break; case GP_FILE_TYPE_RAW: data = Dimera_Get_Full_Image (num, &size, &width, &height, camera, context); if (!data) return GP_ERROR; gp_file_set_data_and_size (file, data, size); /* will take over data ptr ownership */ gp_file_set_mime_type (file, GP_MIME_RAW); gp_file_adjust_name_for_mime_type (file); break; case GP_FILE_TYPE_PREVIEW: data = Dimera_Get_Thumbnail (num, &size, camera); if (!data) return GP_ERROR; gp_file_set_data_and_size (file, data, size); /* will take over data ptr ownership */ gp_file_set_mime_type (file, GP_MIME_PGM); gp_file_adjust_name_for_mime_type (file); break; default: gp_context_error (context, _("Image type is not supported")); return (GP_ERROR_NOT_SUPPORTED); } return GP_OK; }
static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *user_data, GPContext *context) { Camera *camera = user_data; int entry, w, h; /* frame; */ unsigned char *frame_data, *frame_ptr; unsigned char *ppm, *ptr; unsigned char gtable[256]; int start; int datasize, framesize, hdrsize, ppmsize; int nb_frames=1; unsigned char buf[0x8000]; #if 0 /* libgphoto2 likes to search in vain for EXIF data, which isn't there. It's a waste of time, and there should be a way to disable it explicitly. But there isn't. Un-if this if you don't like it, and you can still retrieve the first frame of a video via the frame filename instead. */ if (GP_FILE_TYPE_PREVIEW==type) return GP_ERROR_NOT_SUPPORTED; #endif if (GP_FILE_TYPE_RAW!=type && GP_FILE_TYPE_NORMAL!=type && GP_FILE_TYPE_PREVIEW!=type) { return GP_ERROR_NOT_SUPPORTED; } /* Get the entry number of the photo on the camera */ entry = gp_filesystem_number (camera->fs, folder, filename, context); if (entry < GP_OK) return GP_ERROR_FILE_NOT_FOUND; GP_DEBUG ("Download file %s, entry = %d\n", filename, entry); if (entry >= camera->pl->nb_entries) return GP_ERROR_FILE_NOT_FOUND; /* Fetch entries until the one we need, and toss all but the one we need. * TODO: Either find out how to use the location info in the catalog to * download just the entry needed, or show it is as impossible as it seems. */ /* Change register to DATA, but only if necessary */ if (camera->pl->data_offset == -1) { icl_access_reg(camera->port, DATA); /* Camera starts at the first picture.. */ camera->pl->data_offset = icl_get_start (camera->pl, 0); } start = icl_get_start (camera->pl, entry); datasize = icl_get_size (camera->pl, entry); /* datasize exceeds the actual datasize by 0x100 bytes, which seems to be * 0x100 bytes of filler at the beginning. For now we will treat this extra * 0x100 bytes as junk and just ditch it. */ GP_DEBUG ("data offset at %d, picture at %d\n", camera->pl->data_offset, start); /* Rewind if we're past the requested picture */ if (camera->pl->data_offset > start) { icl_rewind(camera->port, camera->pl); } /* Seek to the requested picture */ while ((camera->pl->data_offset + 0x8000) < start) { icl_read_picture_data(camera->port, buf, 0x8000); camera->pl->data_offset += 0x8000; } if (camera->pl->data_offset < start) { icl_read_picture_data(camera->port, buf, start - camera->pl->data_offset); camera->pl->data_offset = start; } /* Retrieve frames */ framesize = datasize; frame_data = malloc(datasize); if (!frame_data) return GP_ERROR_NO_MEMORY; icl_read_picture_data(camera->port, frame_data, datasize); camera->pl->data_offset += datasize; switch (type) { case GP_FILE_TYPE_PREVIEW: if (icl_get_width_height (camera->pl, entry, &w, &h) >= GP_OK) break; /* Known format, process image */ /* No previewing of raw data */ free (frame_data); return GP_ERROR_NOT_SUPPORTED; case GP_FILE_TYPE_NORMAL: if (icl_get_width_height (camera->pl, entry, &w, &h) >= GP_OK) break; /* Known format, process image */ /* Unsupported format, fallthrough to raw */ case GP_FILE_TYPE_RAW: gp_file_set_mime_type (file, GP_MIME_RAW); gp_file_adjust_name_for_mime_type (file); gp_file_set_data_and_size (file, (char *)frame_data, datasize); return (GP_OK); default: return GP_ERROR_NOT_SUPPORTED; } /* Write the frame(s) */ snprintf((char *)buf, sizeof(buf), "P6\n" "# CREATOR: gphoto2, iClick library\n" "%d %d\n" "255\n", w, h); hdrsize = strlen((char *)buf); ppmsize = (hdrsize + w*h*3) * nb_frames; GP_DEBUG ("ppmsize = %i\n", ppmsize); ptr = ppm = malloc(ppmsize); frame_ptr = frame_data + 0x100; /* Here, we just threw away the "superfluous" first 0x100 bytes */ memcpy(ptr, buf, hdrsize); ptr += hdrsize; gp_bayer_decode (frame_ptr, w , h , ptr, BAYER_TILE_GBRG); gp_gamma_fill_table (gtable, .5); /* The gamma factor is pure guesswork; shooting in the dark. This * is the kind of thing which might be hidden in those 0x100 bytes. */ gp_gamma_correct_single (gtable, ptr, w * h); ptr += w*h*3; gp_file_set_mime_type (file, GP_MIME_PPM); gp_file_set_data_and_size (file, (char *)ppm, ppmsize); free (frame_data); return GP_OK; }