static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *data, GPContext *context) { Camera *camera = data; int n; unsigned char *d; unsigned int size; /* We need file numbers starting with 1 */ CR (n = gp_filesystem_number (camera->fs, folder, filename, context)); n++; switch (type) { case GP_FILE_TYPE_NORMAL: CR (fuji_pic_get (camera, n, &d, &size, context)); break; case GP_FILE_TYPE_PREVIEW: CR (fuji_pic_get_thumb (camera, n, &d, &size, context)); break; default: return (GP_ERROR_NOT_SUPPORTED); } CR (gp_file_set_data_and_size (file, (char *)d, size)); CR (gp_file_set_mime_type (file, GP_MIME_JPEG)); return (GP_OK); }
static int camera_capture_preview (Camera *camera, CameraFile *file, GPContext *context) { unsigned char *frame_data; unsigned char *ppm, *ptr; unsigned char gtable[256]; int size; int w = 320; int h = 240; int b=0x12c40; camera->pl->last_fetched_data = malloc (b); if (!camera->pl->last_fetched_data) { sq_rewind(camera->port, camera->pl); return GP_ERROR_NO_MEMORY; } sq_access_reg(camera->port, CAPTURE); sq_read_picture_data (camera->port, camera->pl->last_fetched_data, b); frame_data = camera->pl->last_fetched_data + 0x40; sq_preprocess(camera->pl->model, 1, 0, frame_data, w, h); /* Now put the data into a PPM image file. */ ppm = malloc (w * h * 3 + 256); if (!ppm) return GP_ERROR_NO_MEMORY; sprintf ((char *)ppm, "P6\n" "# CREATOR: gphoto2, SQ905 library\n" "%d %d\n" "255\n", w, h); ptr = ppm + strlen ((char*)ppm); size = strlen ((char*)ppm) + (w * h * 3); GP_DEBUG ("size = %i\n", size); switch (camera->pl->model) { case SQ_MODEL_POCK_CAM: gp_bayer_decode (frame_data, w , h , ptr, BAYER_TILE_GBRG); break; default: gp_bayer_decode (frame_data, w , h , ptr, BAYER_TILE_BGGR); break; } /* TO DO: * Adapt some postprocessing routine to work here, because results * can vary greatly, depending both on lighting conditions and on * camera model. */ gp_gamma_fill_table (gtable, .5); gp_gamma_correct_single (gtable, ptr, w * h); gp_file_set_mime_type (file, GP_MIME_PPM); gp_file_set_data_and_size (file, (char *)ppm, size); sq_reset(camera->port); sq_access_reg(camera->port, CAPTURE); sq_reset(camera->port); 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 size,image_no,result; unsigned char *data; image_no = gp_filesystem_number(fs, folder, filename, context); if (image_no < GP_OK) return image_no; switch (type) { case GP_FILE_TYPE_NORMAL: result = ultrapocket_getpicture(camera,context,&data,&size,filename); gp_file_set_mime_type (file, GP_MIME_PPM); break; case GP_FILE_TYPE_RAW: result = ultrapocket_getrawpicture(camera, context, &data, &size, filename); gp_file_set_mime_type (file, GP_MIME_PPM); break; case GP_FILE_TYPE_PREVIEW: default: return (GP_ERROR_NOT_SUPPORTED); } if (result < 0) return result; CHECK_RESULT(gp_file_set_data_and_size (file, (char *)data, size)); 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 n; unsigned int size; unsigned char *data; CR (n = gp_filesystem_number (fs, folder, filename, context)); n++; switch (type) { case GP_FILE_TYPE_NORMAL: CR (ricoh_get_pic (camera, context, n, RICOH_FILE_TYPE_NORMAL, &data, &size)); gp_file_set_mime_type (file, GP_MIME_EXIF); break; case GP_FILE_TYPE_PREVIEW: CR (ricoh_get_pic (camera, context, n, RICOH_FILE_TYPE_PREVIEW, &data, &size)); gp_file_set_mime_type (file, GP_MIME_TIFF); break; default: return (GP_ERROR_NOT_SUPPORTED); } gp_file_set_data_and_size (file, (char*)data, size); 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; char *data = NULL; unsigned long int size = 0; switch (type) { case GP_FILE_TYPE_EXIF: gp_file_set_mime_type (file, GP_MIME_RAW); CR (sx330z_get_data (camera, context, filename, &data, &size, SX_THUMBNAIL)); break; case GP_FILE_TYPE_RAW: case GP_FILE_TYPE_NORMAL: gp_file_set_mime_type (file, GP_MIME_JPEG); CR (sx330z_get_data (camera, context, filename, &data, &size, SX_IMAGE)); break; case GP_FILE_TYPE_PREVIEW: default: return (GP_ERROR_NOT_SUPPORTED); } gp_file_set_data_and_size (file, data, size); 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; unsigned char *data = NULL; unsigned int size, mimetype; int index; size = 0; index = gp_filesystem_number (fs, folder, filename, context); if (index < 0) return index; switch (type) { case GP_FILE_TYPE_NORMAL: CHECK (pccam300_get_file (camera->port, context, index, &data, &size, &mimetype)); break; default: return GP_ERROR_NOT_SUPPORTED; } return gp_file_set_data_and_size (file, data, size); }
static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *data, GPContext *context) { Camera *camera = data; int size, nr, result; nr = gp_filesystem_number(fs, folder, filename, context); if(nr < 0) return nr; switch (type) { #if 0 case GP_FILE_TYPE_RAW: result = jd11_get_image_full (camera, nr, &data, (int*) &size, 1); break; #endif case GP_FILE_TYPE_NORMAL: result = mdc800_getImage(camera,nr,&data,&size); break; case GP_FILE_TYPE_PREVIEW: result = mdc800_getThumbnail(camera,nr,&data,&size); break; default: return (GP_ERROR_NOT_SUPPORTED); } if (result < 0) return result; gp_file_set_mime_type (file, GP_MIME_JPEG); gp_file_set_data_and_size(file, data, size); return (GP_OK); }
static int camera_capture_preview (Camera *camera, CameraFile *file, GPContext *context) { char *data; int size, result; result = stv0674_capture_preview (camera->port, &data, &size); if (result < 0) return result; gp_file_set_mime_type (file, GP_MIME_JPEG); return gp_file_set_data_and_size (file, data, size); }
static int camera_capture_preview(Camera *camera, CameraFile *file, GPContext *context) { long size; uint8_t *data; gp_file_set_mime_type (file, GP_MIME_PGM); data = Dimera_Preview( &size, camera, context); if (!data) return GP_ERROR; return gp_file_set_data_and_size (file, data, size); }
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) { char *pos; Camera *camera = user_data; unsigned char *data = NULL; int size,ret; switch (type) { case GP_FILE_TYPE_NORMAL: ret=soundvision_file_get(camera, filename, 0, &data, &size); if (ret<0) return ret; break; case GP_FILE_TYPE_PREVIEW: ret=soundvision_file_get(camera, filename, 1, &data, &size); if (ret<0) return ret; break; default: return GP_ERROR_NOT_SUPPORTED; } if (!data) return GP_ERROR; gp_file_set_data_and_size (file, (char *)data, size); /* Maybe skip below if EXIF data present? */ /* As far as I know we only support JPG and MOV */ /* Maybe some have MP3??? */ pos=strchr (filename, '.'); if (pos) { if ((!strcmp(pos,".JPG")) || ((!strcmp(pos,".jpg")))) gp_file_set_mime_type (file, GP_MIME_JPEG); else if (!strcmp(pos,".MOV")) gp_file_set_mime_type (file, GP_MIME_QUICKTIME); else gp_file_set_mime_type (file, GP_MIME_UNKNOWN); } return GP_OK; }
static int file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list, void *data, GPContext *context) { Camera *camera = data; unsigned int i, filecount, id, size, type; CameraFile *file; CameraFileInfo info; unsigned char *buffer = NULL; int ret, n_img=0, n_avi=0, n_wav=0; char fn[100]; CHECK (pccam300_get_filecount (camera->port, &filecount)); id = gp_context_progress_start (context, filecount, _("Getting file list...")); for (i = 0; i < filecount; i++) { /* Get information */ gp_file_new (&file); ret = pccam300_get_file (camera->port, context, i, &buffer, &size, &type); if (ret < GP_OK) { gp_file_free (file); return ret; } info.audio.fields = GP_FILE_INFO_NONE; info.preview.fields = GP_FILE_INFO_NONE; info.file.fields = GP_FILE_INFO_SIZE | GP_FILE_INFO_TYPE; info.file.size = size; switch (type) { case PCCAM300_MIME_JPEG: strcpy (info.file.type, GP_MIME_JPEG); sprintf (fn, "Image%03i.jpeg", n_img++); break; case PCCAM300_MIME_AVI: strcpy (info.file.type, GP_MIME_AVI); sprintf (fn, "Movie%03i.UNUSABLE", n_avi++); break; case PCCAM300_MIME_WAV: strcpy (info.file.type, GP_MIME_WAV); sprintf (fn, "Audio%03i.UNUSABLE", n_wav++); break; default: break; } if (file) gp_file_set_data_and_size (file, buffer, size); else free (buffer); /* * Append directly to the filesystem instead of to the list, * because we have additional information. * */ gp_filesystem_append (camera->fs, folder, fn, context); gp_filesystem_set_info_noop (camera->fs, folder, fn, info, context); gp_filesystem_set_file_noop (camera->fs, folder, fn, GP_FILE_TYPE_NORMAL, file, context); gp_file_unref (file); gp_context_idle (context); gp_context_progress_update (context, id, i + 1); if (gp_context_cancel(context) == GP_CONTEXT_FEEDBACK_CANCEL) return (GP_ERROR_CANCEL); } gp_context_progress_stop (context, id); return GP_OK; }
int dimagev_get_thumbnail(dimagev_t *dimagev, int file_number, CameraFile *file) { dimagev_packet *p, *r; unsigned char char_buffer, command_buffer[3], *ycrcb_data; char *data; long int size = 0; if ( dimagev->data->host_mode != (unsigned char) 1 ) { dimagev->data->host_mode = (unsigned char) 1; if ( dimagev_send_data(dimagev) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::unable to set host mode"); return GP_ERROR_IO; } } /* First make the command packet. */ command_buffer[0] = 0x0d; command_buffer[1] = (unsigned char)( file_number / 256 ); command_buffer[2] = (unsigned char)( file_number % 256 ); if ( ( p = dimagev_make_packet(command_buffer, 3, 0) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to allocate command packet"); return GP_ERROR_NO_MEMORY; } if ( gp_port_write(dimagev->dev, (char *)p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::unable to send set_data packet"); free(p); return GP_ERROR_IO; } else if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::no response from camera"); free(p); return GP_ERROR_IO; } free(p); switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_thumbnail::camera did not acknowledge transmission"); return dimagev_get_thumbnail(dimagev, file_number, file); /* return GP_ERROR_IO;*/ case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_thumbnail::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_thumbnail::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to read packet"); return GP_ERROR_IO; } if ( ( r = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to strip packet"); free(p); return GP_ERROR_NO_MEMORY; } free(p); /* Unlike normal images, we are guaranteed 9600 bytes *exactly*. */ /* Allocate an extra byte just in case. */ if ( ( ycrcb_data = malloc(9600) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to allocate buffer for file"); free(r); return GP_ERROR_NO_MEMORY; } memcpy(ycrcb_data, r->buffer, (size_t) r->length ); size += r->length - 1 ; free(r); while ( size < 9599 ) { char_buffer=DIMAGEV_ACK; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::unable to send ACK"); free(ycrcb_data); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to read packet"); free(ycrcb_data); return GP_ERROR_IO; } if ( ( r = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to strip packet"); free(p); free(ycrcb_data); return GP_ERROR_NO_MEMORY; } free(p); memcpy(&( ycrcb_data[ ( size + 1) ] ), r->buffer, (size_t) r->length ); size += r->length; free(r); GP_DEBUG( "dimagev_get_thumbnail::current file size is %ld", size); } size++; char_buffer=DIMAGEV_EOT; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::unable to send ACK"); free(ycrcb_data); return GP_ERROR_IO; } if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::no response from camera"); free(ycrcb_data); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_thumbnail::camera did not acknowledge transmission"); free(ycrcb_data); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_thumbnail::camera cancels transmission"); free(ycrcb_data); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_thumbnail::camera responded with unknown value %x", char_buffer); free(ycrcb_data); return GP_ERROR_IO; } data = (char *)dimagev_ycbcr_to_ppm(ycrcb_data); size = 14413; gp_file_set_data_and_size (file, data, size); return GP_OK; }
int dimagev_get_picture(dimagev_t *dimagev, int file_number, CameraFile *file) { int total_packets, i; unsigned long size = 0; dimagev_packet *p, *r; unsigned char char_buffer, command_buffer[3]; char *data; if ( dimagev->data->host_mode != (unsigned char) 1 ) { dimagev->data->host_mode = (unsigned char) 1; if ( dimagev_send_data(dimagev) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to set host mode"); return GP_ERROR_IO; } } GP_DEBUG( "dimagev_get_picture::file_number is %d", file_number); /* Maybe check if it exists? Check the file type? */ /* First make the command packet. */ command_buffer[0] = 0x04; command_buffer[1] = (unsigned char)( file_number / 256 ); command_buffer[2] = (unsigned char)( file_number % 256 ); if ( ( p = dimagev_make_packet(command_buffer, 3, 0) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to allocate command packet"); return GP_ERROR_NO_MEMORY; } if ( gp_port_write(dimagev->dev, (char *)p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to send set_data packet"); free(p); return GP_ERROR_IO; } else if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::no response from camera"); free(p); return GP_ERROR_IO; } free(p); switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_picture::camera did not acknowledge transmission"); return dimagev_get_picture(dimagev, file_number, file); /* return GP_ERROR_IO;*/ case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_picture::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_picture::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to read packet"); return GP_ERROR_IO; } if ( ( r = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to strip packet"); free(p); return GP_ERROR_NO_MEMORY; } free(p); total_packets = (int) r->buffer[0]; /* Allocate an extra byte just in case. */ if ( ( data = malloc((size_t)((993 * total_packets) + 1)) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to allocate buffer for file"); free(r); return GP_ERROR_NO_MEMORY; } memcpy(data, &(r->buffer[1]), (size_t) r->length ); size += ( r->length - 2 ); free(r); for ( i = 0 ; i < ( total_packets -1 ) ; i++ ) { char_buffer=DIMAGEV_ACK; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to send ACK"); free(data); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { /* GP_DEBUG( "dimagev_get_picture::unable to read packet"); return GP_ERROR_IO; */ GP_DEBUG( "dimagev_get_picture::sending NAK to get retry"); char_buffer=DIMAGEV_NAK; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to send NAK"); free(data); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to read packet"); free(data); return GP_ERROR_IO; } } if ( ( r = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to strip packet"); free(data); free(p); return GP_ERROR_NO_MEMORY; } free(p); memcpy(&( data[ ( size + 1) ] ), r->buffer, (size_t) r->length ); size += r->length; free(r); } size++; char_buffer=DIMAGEV_EOT; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to send ACK"); free(data); return GP_ERROR_IO; } if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::no response from camera"); free(data); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_picture::camera did not acknowledge transmission"); free(data); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_picture::camera cancels transmission"); free(data); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_picture::camera responded with unknown value %x", char_buffer); free(data); return GP_ERROR_IO; } gp_file_set_data_and_size (file, data, size); return GP_OK; }
static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *data, GPContext *context) { Camera *camera = data; int idx, size; #ifdef HAVE_GD int ret; gdImagePtr im, rotated; void *gdpng; #endif idx = get_file_idx(camera->pl, folder, filename); if (idx < 0) return idx; if (type == GP_FILE_TYPE_RAW) { unsigned char *raw; size = st2205_read_raw_file (camera, idx, &raw); if (size < 0) return size; gp_file_set_mime_type (file, GP_MIME_RAW); gp_file_set_name (file, filename); gp_file_set_data_and_size (file, (char *)raw, size); return GP_OK; } #ifdef HAVE_GD if (type != GP_FILE_TYPE_NORMAL) return GP_ERROR_NOT_SUPPORTED; im = gdImageCreateTrueColor(camera->pl->width, camera->pl->height); if (im == NULL) return GP_ERROR_NO_MEMORY; ret = st2205_read_file(camera, idx, im->tpixels); if (ret < 0) { gdImageDestroy (im); 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) return GP_ERROR_NO_MEMORY; ret = gp_file_set_mime_type (file, GP_MIME_PNG); if (ret < 0) { gdFree (gdpng); return ret; } ret = gp_file_set_name (file, filename); if (ret < 0) { gdFree (gdpng); return ret; } ret = gp_file_append (file, gdpng, size); gdFree (gdpng); return ret; #else gp_log(GP_LOG_ERROR,"st2205", "GD decompression not supported - no libGD present during build"); return GP_ERROR_NOT_SUPPORTED; #endif }
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) { char path[1024]; int result = GP_OK; struct stat stbuf; int fd, id; unsigned int curread, toread; unsigned char *buf; #ifdef HAVE_LIBEXIF ExifData *data; unsigned int buf_len; #endif /* HAVE_LIBEXIF */ Camera *camera = (Camera*)user_data; result = _get_path (camera->port, folder, filename, path, sizeof(path)); gp_log (GP_LOG_DEBUG, "directory/get_file_func", "%s %s",folder,filename); if (result < GP_OK) return result; gp_log (GP_LOG_DEBUG, "directory/get_file_func", "->%s",path); switch (type) { case GP_FILE_TYPE_NORMAL: #ifdef DEBUG case GP_FILE_TYPE_PREVIEW: #endif fd = open (path,O_RDONLY); if (fd == -1) return GP_ERROR_IO_READ; break; #ifdef HAVE_LIBEXIF case GP_FILE_TYPE_EXIF: data = exif_data_new_from_file (path); if (!data) { gp_context_error (context, _("Could not open '%s'."), path); return (GP_ERROR); } exif_data_save_data (data, &buf, &buf_len); exif_data_unref (data); gp_file_set_data_and_size (file, buf, buf_len); return (GP_OK); #endif /* HAVE_LIBEXIF */ default: return (GP_ERROR_NOT_SUPPORTED); } if (-1 == fstat(fd,&stbuf)) { close (fd); return GP_ERROR_IO_READ; } #define BLOCKSIZE 65536 /* do it in 64kb blocks */ buf = malloc(BLOCKSIZE); if (!buf) { close (fd); return GP_ERROR_NO_MEMORY; } curread = 0; id = gp_context_progress_start (context, (1.0*stbuf.st_size/BLOCKSIZE), _("Getting file...")); GP_DEBUG ("Progress id: %i", id); result = GP_OK; while (curread < stbuf.st_size) { int ret; toread = stbuf.st_size-curread; if (toread>BLOCKSIZE) toread = BLOCKSIZE; ret = read(fd,buf,toread); if (ret == -1) { result = GP_ERROR_IO_READ; break; } curread += ret; gp_file_append (file, buf, ret); gp_context_progress_update (context, id, (1.0*curread/BLOCKSIZE)); gp_context_idle (context); if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) { result = GP_ERROR_CANCEL; break; } #if 0 /* We could take 2 seconds to download this image. everytime. */ /* But actually this driver is used in production by some frontends, * so do not delay at all */ usleep(2000000/(stbuf.st_size/BLOCKSIZE)); #endif } gp_context_progress_stop (context, id); free (buf); close (fd); 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; unsigned char *data = NULL; int number, filetype, flash_file_count = 0; unsigned int size; CHECK (number = gp_filesystem_number (camera->fs, folder, filename, context)); if (cam_has_flash(camera->pl) || cam_has_card(camera->pl) ) { CHECK (spca50x_flash_get_filecount (camera->pl, &flash_file_count)); } switch (type) { case GP_FILE_TYPE_NORMAL: if ( number < flash_file_count) { CHECK (spca50x_flash_get_file (camera->pl, context, &data, &size, number, 0)); CHECK (gp_file_set_mime_type (file, GP_MIME_JPEG)); } else { CHECK (spca50x_sdram_request_file (camera->pl, &data, &size, number-flash_file_count, &filetype)); if (filetype == SPCA50X_FILE_TYPE_IMAGE) { CHECK (gp_file_set_mime_type (file, GP_MIME_JPEG)); } else if (filetype == SPCA50X_FILE_TYPE_AVI) { CHECK (gp_file_set_mime_type (file, GP_MIME_AVI)); } } break; case GP_FILE_TYPE_PREVIEW: if ( number < flash_file_count) { CHECK (spca50x_flash_get_file (camera->pl, context, &data, &size, number, 1)); CHECK (gp_file_set_mime_type (file, GP_MIME_BMP)); } else { CHECK (spca50x_sdram_request_thumbnail (camera->pl, &data, &size, number-flash_file_count, &filetype)); if (filetype == SPCA50X_FILE_TYPE_IMAGE) { CHECK (gp_file_set_mime_type (file, GP_MIME_BMP)); } else if (filetype == SPCA50X_FILE_TYPE_AVI) { CHECK (gp_file_set_mime_type (file, GP_MIME_JPEG)); } } break; default: return GP_ERROR_NOT_SUPPORTED; } if (!data) return GP_ERROR; return gp_file_set_data_and_size (file, (char *)data, size); }
int pdrm11_get_file(CameraFilesystem *fs, const char *filename, CameraFileType type, CameraFile *file, GPPort *port, uint16_t picNum) { uint32_t size = 0; uint16_t thumbsize = 0; uint8_t buf[30]; uint8_t *image; uint8_t temp; int i; int ret; int file_type; gp_port_set_timeout(port,10000); CHECK( pdrm11_select_file(port, picNum) ); if(type == GP_FILE_TYPE_PREVIEW) { CHECK(gp_port_usb_msg_read(port, 0x01, PDRM11_CMD_GET_INFO, picNum, (char *)buf, 8)); file_type = buf[4]; CHECK( gp_port_usb_msg_read(port, 0x01, PDRM11_CMD_GET_THUMBSIZE, picNum, (char *)buf, 14) ); thumbsize = le16atoh( &buf[8] ); /* add 1 to file size only for jpeg thumbnails */ if(file_type == 1) { GP_DEBUG("thumbnail file_type: %s.", "jpeg"); size = (uint32_t)thumbsize + 1; } else if(file_type == 2) { /* NOTE: tiff thumbnails are 160x120 pixel 8bpc rgb images, NOT jpegs... */ GP_DEBUG("thumbnail file_type: %s.", "tiff"); size = (uint32_t)thumbsize; } else { GP_DEBUG("Unknown thumbnail file format!"); return(GP_ERROR_NOT_SUPPORTED); } } else if(type == GP_FILE_TYPE_NORMAL) { CHECK( gp_port_usb_msg_read(port, 0x01, PDRM11_CMD_GET_FILESIZE, picNum, (char *)buf, 26) ); size = le32atoh( &buf[18] ); } else { GP_DEBUG("Unsupported file type!"); return(GP_ERROR_NOT_SUPPORTED); } GP_DEBUG("size: %d 0x%x", size, size); image = malloc(sizeof(char)*size); if(!image) return(GP_ERROR_NO_MEMORY); if(type == GP_FILE_TYPE_PREVIEW) { CHECK_AND_FREE( gp_port_usb_msg_write(port, 0x01, PDRM11_CMD_GET_THUMB, picNum, NULL, 0), image ); } else { CHECK_AND_FREE( gp_port_usb_msg_write(port, 0x01, PDRM11_CMD_GET_PIC, picNum, NULL, 0), image ); } ret = gp_port_read(port, (char *)image, size); if(ret != size) { GP_DEBUG("failed to read from port. Giving it one more try..."); ret = gp_port_read(port, (char *)image, size); if(ret != size) { GP_DEBUG("gp_port_read returned %d 0x%x. size: %d 0x%x", ret, ret, size, size); free (image); return(GP_ERROR_IO_READ); } } /* swap the bytes for the thumbnail, but not the file */ if(type == GP_FILE_TYPE_PREVIEW) { for(i=0; i<size; i+=2) { temp = image[i]; image[i] = image[i+1]; image[i+1] = temp; } } gp_file_set_mime_type(file, GP_MIME_JPEG); gp_file_set_data_and_size(file, (char *)image, size); 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; }
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 w, h = 0, b = 0, k; unsigned char *pic_data, *pic_buffer, *pic_output = NULL; int HEADERSIZE=16; int outputsize; unsigned long start_of_photo; unsigned int downloadsize = 0; int filled = 0; GP_DEBUG ("Downloading pictures!\n"); if(!camera->pl->data_reg_opened) jl2005c_open_data_reg (camera, camera->port); /* These are cheap cameras. There ain't no EXIF data. */ if (GP_FILE_TYPE_EXIF == type) return GP_ERROR_FILE_EXISTS; /* Get the number of the photo on the camera */ k = gp_filesystem_number (camera->fs, "/", filename, context); h = camera->pl->table[16 * k + 4] << 3; w = camera->pl->table[16 * k + 5] << 3; GP_DEBUG ("height is %i\n", h); b = jl2005c_get_pic_data_size(camera->pl, camera->pl->table, k); GP_DEBUG("b = %i = 0x%x bytes\n", b,b); start_of_photo = jl2005c_get_start_of_photo(camera->pl, camera->pl->table, k); GP_DEBUG("start_of_photo number %i = 0x%lx \n", k,start_of_photo); pic_buffer = malloc(b + HEADERSIZE); if (!pic_buffer) return GP_ERROR_NO_MEMORY; memset(pic_buffer, 0, b + HEADERSIZE); GP_DEBUG ("buffersize b+16 = %i = 0x%x bytes\n", b+16,b+16); /* Copy info line for photo from allocation table, as header */ memcpy(pic_buffer, camera->pl->table + 16 * k, 16); pic_data = pic_buffer+HEADERSIZE; /* * Camera can download in blocks of 0xfa00, with only the last block * possibly smaller. So first we set up a cache of that size * (if it is not set up already) to hold raw data. If one tries * instead to download one photo at a time, the camera will misbehave; * data will be lost or corrupted. The dog will bite you, too. */ if (!(camera->pl->data_cache)) { camera->pl->data_cache = malloc (MAX_DLSIZE); } if (!(camera->pl->data_cache)) { GP_DEBUG ("no cache memory allocated!\n"); return GP_ERROR_NO_MEMORY; } /* Is there data in the cache, or not? If yes, read from it into the * current photo, immediately. Update settings. But first two sanity * checks. */ if (start_of_photo < camera->pl->bytes_put_away) { GP_DEBUG("photo number %i starts in a funny place!\n",k); /* We need to start all over again to get this photo. */ jl2005c_reset(camera, camera->port); jl2005c_init (camera, camera->port, camera->pl); } if (start_of_photo+b > camera->pl->total_data_in_camera) { GP_DEBUG ("Photo runs past end of data. Exiting. \n"); GP_DEBUG ("Block size may be wrong for this camera\n"); return (GP_ERROR); } /* * This while loop is entered if the photo number k-1 was not requested * and thus has not been downloaded. The camera's rudimentary hardware * obliges us to download all data consecutively and toss whatever * portion of said data that we do not intend to use. The rudimentary * hardware also does not like to stop downloading at the end of one * photo and then to start on the next. It wants to keep getting data * in size 0xfa00 increments, and only the last block can be smaller. * To do otherwise will cause data to be lost or corrupted. * * Whoever tries to simplify this convoluted and ugly procedure is * warned that the obvious simplifications, while much prettier, * just won't work. A kutya harap. */ while (camera->pl->bytes_read_from_camera <= start_of_photo) { camera->pl->data_to_read = camera->pl->total_data_in_camera - camera->pl->bytes_read_from_camera; downloadsize = MAX_DLSIZE; if (camera->pl->data_to_read < downloadsize) downloadsize = camera->pl->data_to_read; GP_DEBUG("downloadsize = 0x%x\n", downloadsize); if (downloadsize) jl2005c_read_data ( camera->port, (char *) camera->pl->data_cache, downloadsize); camera->pl->bytes_read_from_camera += downloadsize; } camera->pl->bytes_put_away=start_of_photo; if (camera->pl->bytes_read_from_camera > start_of_photo) { if(start_of_photo + b <= camera->pl->bytes_read_from_camera) { memcpy(pic_data, camera->pl->data_cache + (start_of_photo % MAX_DLSIZE) , b); camera->pl->bytes_put_away += b; /* * Photo data is contained in what is already * downloaded. * Jump immediately to process the photo. */ } else { /* Photo starts in one 0xfa00-sized download and ends * in another */ filled = camera->pl->bytes_read_from_camera - start_of_photo; memcpy(pic_data, camera->pl->data_cache + (start_of_photo % MAX_DLSIZE), filled); camera->pl->bytes_put_away += filled; } } while (camera->pl->bytes_put_away < start_of_photo + b ) { camera->pl->data_to_read = camera->pl->total_data_in_camera - camera->pl->bytes_read_from_camera; downloadsize = MAX_DLSIZE; if (camera->pl->data_to_read < downloadsize) downloadsize = camera->pl->data_to_read; GP_DEBUG("downloadsize = 0x%x\n", downloadsize); if (downloadsize) jl2005c_read_data ( camera->port, (char *) camera->pl->data_cache, downloadsize); camera->pl->bytes_read_from_camera += downloadsize; if (camera->pl->bytes_read_from_camera >= start_of_photo + b ) { GP_DEBUG("THIS ONE?\n"); memcpy(pic_data+filled, camera->pl->data_cache, b - filled); camera->pl->bytes_put_away += b - filled; break; } else { GP_DEBUG("THIS ONE??\n"); if (!downloadsize) break; memcpy(pic_data + filled, camera->pl->data_cache, downloadsize); camera->pl->bytes_put_away += downloadsize; filled += downloadsize; } } if (type == GP_FILE_TYPE_RAW) { gp_file_set_mime_type(file, GP_MIME_RAW); gp_file_set_data_and_size(file, (char *)pic_buffer , b+16 ); return GP_OK; #ifdef HAVE_LIBJPEG } else if (type == GP_FILE_TYPE_PREVIEW) { if (!camera->pl->can_do_capture) return GP_ERROR_NOT_SUPPORTED; outputsize = (pic_buffer[9] & 0xf0) * 192 + 256; GP_DEBUG("pic_buffer[9] is 0x%02x\n", pic_buffer[9]); GP_DEBUG("Thumbnail outputsize = 0x%x = %d\n", outputsize, outputsize); if (outputsize == 256) { GP_DEBUG("Frame %d has no thumbnail.\n", k); return GP_OK; } pic_output = calloc(outputsize, 1); if (!pic_output) return GP_ERROR_NO_MEMORY; outputsize = jl2005bcd_decompress(pic_output, pic_buffer, b + 16, 1); GP_DEBUG("Thumbnail outputsize recalculated is 0x%x = %d\n", outputsize, outputsize); gp_file_set_mime_type(file, GP_MIME_PPM); gp_file_set_data_and_size(file, (char *)pic_output, outputsize); } else if (type == GP_FILE_TYPE_NORMAL) { outputsize = 3 * w * h + 256; pic_output = calloc(outputsize, 1); if (!pic_output) return GP_ERROR_NO_MEMORY; outputsize = jl2005bcd_decompress(pic_output, pic_buffer, b + 16, 0); gp_file_set_mime_type(file, GP_MIME_PPM); gp_file_set_data_and_size(file, (char *)pic_output, outputsize); #endif } else 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 w=0, h=0, b=0; int k, res; unsigned char *data; unsigned char *jpeg_out = NULL; int file_size; unsigned char jpeg_format; /* Get the entry number of the photo on the camera */ k = gp_filesystem_number (camera->fs, "/", filename, context); if (GP_FILE_TYPE_EXIF==type) return GP_ERROR_FILE_EXISTS; if (GP_FILE_TYPE_RAW!=type && GP_FILE_TYPE_NORMAL !=type && GP_FILE_TYPE_PREVIEW!=type) return GP_ERROR_NOT_SUPPORTED; res = clicksmart_get_res_setting (camera->pl, k); switch (res) { case 0: w = 352; h = 288; jpeg_format = JPEG_CIF_FORMAT; break; case 1: case 3: w = 176; h = 144; jpeg_format = JPEG_QCIF_FORMAT; break; default: GP_DEBUG ( "Unknown resolution setting %i\n", res); return GP_ERROR; } data = malloc (w*h); if(!data) return GP_ERROR_NO_MEMORY; GP_DEBUG("Fetch entry %i\n", k); b = clicksmart_read_pic_data (camera->pl, camera->port, data, k); if (GP_FILE_TYPE_RAW == type) { /* type is GP_FILE_TYPE_RAW */ gp_file_set_mime_type (file, GP_MIME_RAW); gp_file_set_data_and_size (file, (char *)data, b); /* Reset camera when done, for more graceful exit. */ if (k +1 == camera->pl->num_pics) { clicksmart_reset (camera->port); } return GP_OK; } GP_DEBUG ("size = %i\n", b); /* It looks as though o_size = b */ /* It seems that qIndex is byte7, which is always 3, so I use that. */ file_size = b + 589 + 1024 * 10; jpeg_out = malloc(file_size); if (!jpeg_out) { free(data); return GP_ERROR_NO_MEMORY; } GP_DEBUG("width: %d, height: %d, data size: %d\n", w, h, b); create_jpeg_from_data (jpeg_out, data, 3, w, h, jpeg_format, b, &file_size, 0, 0); gp_file_set_mime_type (file, GP_MIME_JPEG); gp_file_set_data_and_size (file, (char *)jpeg_out, file_size); /* Reset camera when done, for more graceful exit. */ if (k +1 == camera->pl->num_pics) { clicksmart_reset (camera->port); } free(data); 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 status = GP_OK; int w, h = 0, k; int i,j; int b = 0; int compressed = 0; unsigned char header[5] = "\xff\xff\xff\xff\x55"; unsigned int size; unsigned char *data; unsigned char *image_start; unsigned char *p_data=NULL; unsigned char *ppm=NULL, *ptr=NULL; unsigned char gtable[256]; unsigned char temp; GP_DEBUG ("Downloading pictures!\n"); /* These are cheap cameras. There ain't no EXIF data. So kill this. */ if (GP_FILE_TYPE_EXIF == type) return GP_ERROR_FILE_EXISTS; /* Get the number of the photo on the camera */ k = gp_filesystem_number (camera->fs, "/", filename, context); GP_DEBUG ("Filesystem number is %i\n",k); b = jl2005a_get_pic_data_size(camera->port, k); GP_DEBUG("b = %i = 0x%x bytes\n", b,b); w = jl2005a_get_pic_width(camera->port); GP_DEBUG ("width is %i\n", w); h = jl2005a_get_pic_height(camera->port); GP_DEBUG ("height is %i\n", h); /* Image data to be downloaded contains header and footer bytes */ data = malloc (b+14); if (!data) return GP_ERROR_NO_MEMORY; jl2005a_read_picture_data (camera, camera->port, data, b+14); if (memcmp(header,data,5) != 0) /* Image data is corrupted! Repeat the operation. */ jl2005a_read_picture_data (camera, camera->port, data, b+14); if (GP_FILE_TYPE_RAW == type) { gp_file_set_mime_type(file, GP_MIME_RAW); gp_file_set_name(file, filename); gp_file_set_data_and_size(file, (char *)data , b+14 ); return GP_OK; } /* Now get ready to put the data into a PPM image file. */ p_data = malloc( w*h ); if (!p_data) { status = GP_ERROR_NO_MEMORY; goto end; } image_start=data+5; if (w == 176) { for (i=1; i < h; i +=4){ for (j=1; j< w; j ++){ temp=image_start[i*w+j]; image_start[i*w+j] = image_start[(i+1)*w+j]; image_start[(i+1)*w+j] = temp; } } if (h == 72) { compressed = 1; h = 144; } } else if (h == 144) { compressed = 1; h = 288; } p_data = malloc( w*h ); if (!p_data) { status = GP_ERROR_NO_MEMORY; goto end; } if (compressed) jl2005a_decompress (image_start, p_data, w, h); else memcpy(p_data, image_start, w*h); ppm = malloc (w * h * 3 + 256); /* room for data and header */ if (!ppm) { status = GP_ERROR_NO_MEMORY; goto end; } sprintf ((char *)ppm, "P6\n" "# CREATOR: gphoto2, JL2005A library\n" "%d %d\n" "255\n", w, h); size = strlen ((char *)ppm); ptr = ppm + size; size = size + (w * h * 3); GP_DEBUG ("size = %i\n", size); gp_ahd_decode (p_data, w , h, ptr, BAYER_TILE_BGGR); free(p_data); gp_gamma_fill_table (gtable, .65); gp_gamma_correct_single (gtable, ptr, w * h); gp_file_set_mime_type (file, GP_MIME_PPM); gp_file_set_name (file, filename); gp_file_set_data_and_size (file, (char *)ppm, size); end: free(data); return status; 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 i, w, h, b, entry, frame, is_in_clip; int nb_frames, to_fetch; int do_preprocess; unsigned char comp_ratio; unsigned char *frame_data, *rawdata; unsigned char *ppm, *ptr; unsigned char gtable[256]; int size; int this_cam_tile; if (GP_FILE_TYPE_EXIF ==type) return GP_ERROR_FILE_EXISTS; 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 = -1; if (0==strcmp(folder, "/")) { i = atoi(filename+4); do { do entry++; while (sq_is_clip(camera->pl, entry) && entry<camera->pl->nb_entries); i--; } while (i>0); if (entry == camera->pl->nb_entries) return GP_ERROR_FILE_NOT_FOUND; frame = 0; is_in_clip = 0; } else { i = atoi(folder+1+4); do { do entry++; while (!sq_is_clip(camera->pl, entry) && entry<camera->pl->nb_entries); i--; } while (i>0); if (entry == camera->pl->nb_entries) return GP_ERROR_DIRECTORY_NOT_FOUND; frame = atoi(filename+4)-1; if (frame >= sq_get_num_frames(camera->pl, entry)) return GP_ERROR_FILE_NOT_FOUND; is_in_clip = 1; } GP_DEBUG ("Download file %s from %s, entry = %d, frame = %d\n", filename, folder, entry, frame); /* Fetch entries until the one we need, and toss all before * 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 to be. */ GP_DEBUG ("last entry was %d\n", camera->pl->last_fetched_entry); /* Change register to DATA, but only if necessary */ if ((camera->pl->last_fetched_entry == -1) || ((is_in_clip) && (frame == 0)) ) sq_access_reg(camera->port, DATA); if (camera->pl->last_fetched_entry > entry) { sq_rewind(camera->port, camera->pl); } do_preprocess = 0; do { to_fetch = camera->pl->last_fetched_entry; if (to_fetch < entry) { to_fetch++; free(camera->pl->last_fetched_data); camera->pl->last_fetched_data = NULL; } nb_frames = sq_get_num_frames(camera->pl, to_fetch); comp_ratio = sq_get_comp_ratio (camera->pl, to_fetch); w = sq_get_picture_width (camera->pl, to_fetch); switch (w) { case 176: h = 144; break; case 640: h = 480; break; case 320: h = 240; break; default: h = 288; break; } b = nb_frames * w * h / comp_ratio; do_preprocess = 1; if (camera->pl->last_fetched_data) break; camera->pl->last_fetched_data = malloc (nb_frames*w*h); if (!camera->pl->last_fetched_data) { sq_rewind(camera->port, camera->pl); return GP_ERROR_NO_MEMORY; } GP_DEBUG("Fetch entry %i\n", to_fetch); sq_read_picture_data (camera->port, camera->pl->last_fetched_data, b); camera->pl->last_fetched_entry = to_fetch; } while (camera->pl->last_fetched_entry<entry); frame_data = camera->pl->last_fetched_data+(w*h)*frame/comp_ratio; /* sq_preprocess ( ) turns the photo right-side-up and for some * models must also de-mirror the photo */ if (GP_FILE_TYPE_RAW!=type) { if (do_preprocess) { sq_preprocess(camera->pl->model, comp_ratio, is_in_clip, frame_data, w, h); } /* * Now put the data into a PPM image file. */ ppm = malloc (w * h * 3 + 256); /* room for data + header */ if (!ppm) { return GP_ERROR_NO_MEMORY; } sprintf ((char *)ppm, "P6\n" "# CREATOR: gphoto2, SQ905 library\n" "%d %d\n" "255\n", w, h); size = strlen ((char *)ppm); ptr = ppm + size; switch (camera->pl->model) { case SQ_MODEL_POCK_CAM: case SQ_MODEL_MAGPIX: this_cam_tile = BAYER_TILE_GBRG; break; default: this_cam_tile = BAYER_TILE_BGGR; break; } size = size + (w * h * 3); GP_DEBUG ("size = %i\n", size); if (comp_ratio>1) { rawdata = malloc (w*h); if (!rawdata) return GP_ERROR_NO_MEMORY; sq_decompress (camera->pl->model, rawdata, frame_data, w, h); gp_gamma_fill_table (gtable, .65); } else { rawdata = frame_data; gp_gamma_fill_table (gtable, .55); } gp_ahd_decode (rawdata, w , h , ptr, this_cam_tile); gp_gamma_correct_single (gtable, ptr, w * h); gp_file_set_mime_type (file, GP_MIME_PPM); gp_file_set_data_and_size (file, (char *)ppm, size); } else { /* type is GP_FILE_TYPE_RAW */ size = w*h/comp_ratio; rawdata = malloc (size+16); if (!rawdata) return GP_ERROR_NO_MEMORY; memcpy (rawdata, frame_data, size); memcpy (rawdata+size,camera->pl->catalog+16*entry,16); gp_file_set_mime_type (file, GP_MIME_RAW); gp_file_set_data_and_size (file, (char *)rawdata, size+16); } /* Reset camera when done, for more graceful exit. */ if ((!(is_in_clip)&&(entry +1 == camera->pl->nb_entries)) || ((is_in_clip)&& (frame +1 == nb_frames ))) sq_reset (camera->port); return GP_OK; }