예제 #1
0
파일: library.c 프로젝트: JohnChu/Snoopy
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;
}
예제 #2
0
파일: library.c 프로젝트: Jay314/libgphoto2
static int
get_file_func(CameraFilesystem *fs, const char *folder, const char *filename,
		CameraFileType type, CameraFile *file, void *user_data,
							GPContext *context)
{
	int status = GP_OK;
	Camera *camera = user_data;
	int w, h, b;
	int k, next;
	unsigned char comp_ratio;
	unsigned char lighting;
	unsigned char *data = NULL;
	unsigned char *p_data = NULL;
	unsigned char *ppm;
	unsigned char *ptr;
	unsigned char gtable[256];
	int size;

	if (!camera->pl->init_done)
		digi_init (camera->port, camera->pl);

	/* 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;
	}

	next = camera->pl->last_fetched_entry +1;
	while (next < k) {
		b = digi_get_data_size (camera->pl, next);
		data = malloc(b);
		if(!data) return GP_ERROR_NO_MEMORY;
		digi_read_picture_data (camera->port, data, b, next);
		free(data);
		next ++;
	}

	comp_ratio = digi_get_comp_ratio (camera->pl, k);
	w = digi_get_picture_width (camera->pl, k);
	switch (w) {
	case 176: h = 144; break;
	case 640: h = 480; break;
	case 320: h = 240; break;
	default:  h = 288; break;
	}
	lighting = camera->pl->catalog[k*0x10+0x0b];
	b = digi_get_data_size (camera->pl, k);
	if (!b) {
		GP_DEBUG("Photo number %i deleted?\n",k+1);
		camera->pl->last_fetched_entry = k;
		return GP_OK;
	}
	data = malloc (w*h);
	if(!data) return GP_ERROR_NO_MEMORY;

	GP_DEBUG("Fetch entry %i\n", k);
	digi_read_picture_data (camera->port, data, b, k);
	camera->pl->last_fetched_entry = k;

	if (GP_FILE_TYPE_RAW == type) {	/* type is GP_FILE_TYPE_RAW */
		size = b;
		gp_file_set_mime_type (file, GP_MIME_RAW);
		gp_file_append(file, (char *)data, size);
		/* Save photo's catalog entry as a footer for the raw file */
		gp_file_append(file, (char *)camera->pl->catalog
						+ k * 0x10, 0x10);
		/* Reset camera when done, for more graceful exit. */
		if (k +1 == camera->pl->nb_entries) {
			digi_rewind (camera->port, camera->pl);
		}
		free(data);
		return(GP_OK);
	}

	/*
	 * Now put the data into a PPM image file.
	 */

	ppm = malloc (w * h * 3 + 256); /* room for data + header */
	if (!ppm) {
		status = GP_ERROR_NO_MEMORY;
		goto end;
	}
	snprintf ((char *)ppm, 64,
			"P6\n"
			"# CREATOR: gphoto2, SQ905C 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);
	p_data = malloc(w * h);
	if (!p_data) {
		status =  GP_ERROR_NO_MEMORY;
		goto end;
	}
	if(comp_ratio) {
		digi_decompress (p_data, data, w, h);
	} else
		memcpy(p_data, data, w * h);
	gp_ahd_decode(p_data, w , h , ptr, BAYER_TILE_BGGR);
	free(p_data);
	digi_postprocess(w, h, ptr);
	if (lighting < 0x40) {
	GP_DEBUG(
		"Low light condition. Using default gamma. \
						No white balance.\n");
		gp_gamma_fill_table (gtable, .65);
		gp_gamma_correct_single(gtable,ptr,w*h);
	} else
예제 #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 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;
}