示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
}