コード例 #1
0
ファイル: library.c プロジェクト: Dvizhenka/libgphoto2
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);
}
コード例 #2
0
ファイル: ultrapocket.c プロジェクト: AleksKolkov/libgphoto2
/* Different camera types (pocket digital/generic)
 * use a different protocol - have to differetiate.
 */
int
ultrapocket_getpicture(Camera *camera, GPContext *context, unsigned char **pdata, int *size, const char *filename)
{
    char	   *savelocale;
    char           ppmheader[200];
    unsigned char *rawdata,*outdata;
    int            width, height, result;
    size_t         outsize;
    int            imgstart = 0;
    int            pc, pmmhdr_len;
    BayerTile      tile;
#if DO_GAMMA
    unsigned char  gtable[256];
#endif

    switch (camera->pl->up_type) {
     case BADGE_CARDCAM:
     case BADGE_FLATFOTO:
     case BADGE_GENERIC:
     case BADGE_ULTRAPOCKET:
     case BADGE_AXIA:
	CHECK_RESULT(getpicture_generic(camera, context, &rawdata, &width, &height, &imgstart, filename));
	break;
     case BADGE_LOGITECH_PD:
	CHECK_RESULT(getpicture_logitech_pd(camera, context, &rawdata, filename));
	width = 640;
	height = 480;
	imgstart = 0x29;
	break;
     default:
	return GP_ERROR;
    }

   tile = BAYER_TILE_BGGR;

   savelocale = setlocale (LC_ALL, "C");
   snprintf (ppmheader, sizeof(ppmheader), "P6\n"
	    "# CREATOR: gphoto2, ultrapocket library,"
	    " assuming Bayer tile %s, interpolated"
#if DO_GAMMA
	    ", gamma %.2f"
#endif
	    "\n%d %d\n"
	    "255\n", BayerTileNames[tile], 
#if DO_GAMMA
	    GAMMA_NUMBER,
#endif
	    width, height);
   setlocale (LC_ALL, savelocale);

   /* Allocate memory for Interpolated ppm image */
   pmmhdr_len = strlen(ppmheader);
   outsize = ((long)width + 4) * height * 3 + pmmhdr_len;
   outdata = malloc(outsize);
   if (!outdata) {
     free (rawdata);
     return (GP_ERROR_NO_MEMORY);
   }

   /* Set header */
   strcpy((char *)outdata, ppmheader);

   /* Decode and interpolate the Bayer tiles */
   result = gp_bayer_decode((rawdata+imgstart), width+4, height,
			    &outdata[pmmhdr_len], tile);

   /* and chop the spare 4 pixels off the RHS */
   for (pc = 1; pc < height; pc++) {
      memmove(outdata + pmmhdr_len + ((long)width * pc * 3), 
              outdata + pmmhdr_len + (((long)width + 4) * pc * 3), 
              ((long)width) * 3);
   }
   /* modify outsize to reflect trim */
   outsize = ((long)width) * height * 3 + pmmhdr_len;

   free(rawdata);
   if (result < 0) {
      free (outdata);
      return (result);
   }

#if DO_GAMMA
   gp_gamma_fill_table(gtable, GAMMA_NUMBER);
   gp_gamma_correct_single(gtable, &outdata[pmmhdr_len], height * width);
#endif

   *pdata = outdata;
   *size  = outsize;
   return GP_OK;
}
コード例 #3
0
ファイル: mars.c プロジェクト: CastorGemini/libgphoto2
int
mars_white_balance (unsigned char *data, unsigned int size, float saturation,
						float image_gamma)
{
	int x, r, g, b, max, d;
	double r_factor, g_factor, b_factor, max_factor;
	int htable_r[0x100], htable_g[0x100], htable_b[0x100];
	unsigned char gtable[0x100];
	double new_gamma, gamma=1.0;

	/* ------------------- GAMMA CORRECTION ------------------- */

	histogram(data, size, htable_r, htable_g, htable_b);
	x = 1;
	for (r = 48; r < 208; r++)
	{
		x += htable_r[r]; 
		x += htable_g[r];
		x += htable_r[r]; 
	}
	new_gamma = sqrt((double) (x * 1.5) / (double) (size * 3));
	x=0;
	GP_DEBUG("Provisional gamma correction = %1.2f\n", new_gamma);
	/* Recalculate saturation factor for later use. */
	saturation=saturation*new_gamma*new_gamma;
	GP_DEBUG("saturation = %1.2f\n", saturation);
	if(new_gamma >= 1.0)
		gamma = new_gamma;
	else
		gamma = image_gamma;

	GP_DEBUG("Gamma correction = %1.2f\n", gamma);
	gp_gamma_fill_table(gtable, gamma);

	/* ---------------- BRIGHT DOTS ------------------- */
	max = size / 200; 
	histogram(data, size, htable_r, htable_g, htable_b);

	for (r=0xfe, x=0; (r > 32) && (x < max); r--)  
		x += htable_r[r]; 
	for (g=0xfe, x=0; (g > 32) && (x < max); g--) 
		x += htable_g[g];
	for (b=0xfe, x=0; (b > 32) && (x < max); b--) 
		x += htable_b[b];
	r_factor = (double) 0xfd / r;
	g_factor = (double) 0xfd / g;
	b_factor = (double) 0xfd / b;

	max_factor = r_factor;
	if (g_factor > max_factor) max_factor = g_factor;
	if (b_factor > max_factor) max_factor = b_factor;

	if (max_factor >= 2.5) {
		r_factor = (r_factor / max_factor) * 2.5;
		g_factor = (g_factor / max_factor) * 2.5;
		b_factor = (b_factor / max_factor) * 2.5;
	}
	GP_DEBUG("White balance (bright): r=%1d, g=%1d, b=%1d, fr=%1.3f, fg=%1.3f, fb=%1.3f\n", r, g, b, r_factor, g_factor, b_factor);
	if (max_factor <= 2.5) {
		for (x = 0; x < (size * 3); x += 3)
		{
			d = (data[x+0]<<8) * r_factor;
			d >>=8;
			if (d > 0xff) { d = 0xff; }
			data[x+0] = d;
			d = (data[x+1]<<8) * g_factor;
			d >>=8;
			if (d > 0xff) { d = 0xff; }
			data[x+1] = d;
			d = (data[x+2]<<8) * b_factor;
			d >>=8;
			if (d > 0xff) { d = 0xff; }
			data[x+2] = d;
		}
	}
	/* ---------------- DARK DOTS ------------------- */
	max = size / 200;  /*  1/200 = 0.5%  */
	histogram(data, size, htable_r, htable_g, htable_b);

	for (r=0, x=0; (r < 96) && (x < max); r++)  
		x += htable_r[r]; 
	for (g=0, x=0; (g < 96) && (x < max); g++) 
		x += htable_g[g];
	for (b=0, x=0; (b < 96) && (x < max); b++) 
		x += htable_b[b];

	r_factor = (double) 0xfe / (0xff-r);
	g_factor = (double) 0xfe / (0xff-g);
	b_factor = (double) 0xfe / (0xff-b);

	max_factor = r_factor;
	if (g_factor > max_factor) max_factor = g_factor;
	if (b_factor > max_factor) max_factor = b_factor;

	if (max_factor >= 1.15) {
		r_factor = (r_factor / max_factor) * 1.15;
		g_factor = (g_factor / max_factor) * 1.15;
		b_factor = (b_factor / max_factor) * 1.15;
	}
	GP_DEBUG(
	"White balance (dark): r=%1d, g=%1d, b=%1d, fr=%1.3f, fg=%1.3f, fb=%1.3f\n", 
				r, g, b, r_factor, g_factor, b_factor);

	for (x = 0; x < (size * 3); x += 3)
	{
		d = (int) 0xff08-(((0xff-data[x+0])<<8) * r_factor);
		d >>= 8;
		if (d < 0) { d = 0; }
		data[x+0] = d;
		d = (int) 0xff08-(((0xff-data[x+1])<<8) * g_factor);
		d >>= 8;
		if (d < 0) { d = 0; }
		data[x+1] = d;
		d = (int) 0xff08-(((0xff-data[x+2])<<8) * b_factor);
		d >>= 8;
		if (d < 0) { d = 0; }
		data[x+2] = d;
	}

	/* ------------------ COLOR ENHANCE ------------------ */

	if(saturation > 0.0) {
		for (x = 0; x < (size * 3); x += 3)
		{
			r = data[x+0]; g = data[x+1]; b = data[x+2];
			d = (int) (r + g + b) /3.;
			if ( r > d )
				r = r + (int) ((r - d) * (0xff-r)/(0x100-d) * saturation);
			else 
				r = r + (int) ((r - d) * (0xff-d)/(0x100-r) * saturation);
			if (g > d)
				g = g + (int) ((g - d) * (0xff-g)/(0x100-d) * saturation);
			else 
				g = g + (int) ((g - d) * (0xff-d)/(0x100-g) * saturation);
			if (b > d)
				b = b + (int) ((b - d) * (0xff-b)/(0x100-d) * saturation);
			else 
				b = b + (int) ((b - d) * (0xff-d)/(0x100-b) * saturation);
			data[x+0] = CLAMP(r);
			data[x+1] = CLAMP(g);
			data[x+2] = CLAMP(b);
		}
	}
	return 0;
}
コード例 #4
0
ファイル: sonix.c プロジェクト: CastorGemini/libgphoto2
int
white_balance (unsigned char *data, unsigned int size, float saturation)
{
	int x, r, g, b, max, d;
	double r_factor, g_factor, b_factor, max_factor, MAX_FACTOR=1.6;
	int htable_r[256], htable_g[256], htable_b[256];
	unsigned char gtable[256];
	double new_gamma, gamma;

	/* ------------------- GAMMA CORRECTION ------------------- */

	histogram(data, size, htable_r, htable_g, htable_b);
	x = 1;
	for (r = 64; r < 192; r++)
	{
		x += htable_r[r]; 
		x += htable_g[r];
		x += htable_b[r];
	}
        gamma = sqrt((double) (x ) / (double) (size * 2));
        GP_DEBUG("Provisional gamma correction = %1.2f\n", gamma);

	if(gamma < .1) {
		new_gamma = .50;
		MAX_FACTOR=1.2;
	}
	else if (gamma < 0.60) 
		new_gamma = 0.60;
	else
		new_gamma = gamma;
        if (new_gamma > 1.2) new_gamma = 1.2;
        GP_DEBUG("Gamma correction = %1.2f\n", new_gamma);
	gp_gamma_fill_table(gtable, new_gamma);
	gp_gamma_correct_single(gtable,data,size);

	/* ---------------- BRIGHT DOTS ------------------- */
	max = size / 200; 
	histogram(data, size, htable_r, htable_g, htable_b);

	for (r=254, x=0; (r > 64) && (x < max); r--)  
		x += htable_r[r]; 
	for (g=254, x=0; (g > 64) && (x < max); g--) 
		x += htable_g[g];
	for (b=254, x=0; (b > 64) && (x < max); b--) 
		x += htable_b[b];

	r_factor = (double) 254 / r;
	g_factor = (double) 254 / g;
	b_factor = (double) 254 / b;
	max_factor = r_factor;
	if (g_factor > max_factor) max_factor = g_factor;
	if (b_factor > max_factor) max_factor = b_factor;

	if (max_factor > MAX_FACTOR) {

		r_factor = (r_factor / max_factor) * MAX_FACTOR;
		g_factor = (g_factor / max_factor) * MAX_FACTOR;
		b_factor = (b_factor / max_factor) * MAX_FACTOR;
	}

	GP_DEBUG("White balance (bright): r=%1d, g=%1d, b=%1d, fr=%1.3f, fg=%1.3f, fb=%1.3f\n", r, g, b, r_factor, g_factor, b_factor);

	for (x = 0; x < (size * 3); x += 3)
	{
		d = (int) data[x+0] * r_factor;
		if (d > 255) { d = 255; }
		data[x+0] = d;
		d = (int) data[x+1] * g_factor;
		if (d > 255) { d = 255; }
		data[x+1] = d;
		d = (int) data[x+2] * b_factor;
		if (d > 255) { d = 255; }
		data[x+2] = d;
	}
	/* ---------------- DARK DOTS ------------------- */


	max = size / 200;  /*  1/200 = 0.5%  */

	histogram(data, size, htable_r, htable_g, htable_b);

	for (r=0, x=0; (r < 64) && (x < max); r++)  
		x += htable_r[r]; 
	for (g=0, x=0; (g < 64) && (x < max); g++) 
		x += htable_g[g];
	for (b=0, x=0; (b < 64) && (x < max); b++) 
		x += htable_b[b];

	r_factor = (double) 254 / (255-r);
	g_factor = (double) 254 / (255-g);
	b_factor = (double) 254 / (255-b);

	GP_DEBUG("White balance (dark): r=%1d, g=%1d, b=%1d, fr=%1.3f, fg=%1.3f, fb=%1.3f\n", r, g, b, r_factor, g_factor, b_factor);

	for (x = 0; x < (size * 3); x += 3)
	{
		d = (int) 255-((255-data[x+0]) * r_factor);
		if (d < 0) { d = 0; }
		data[x+0] = d;
		d = (int) 255-((255-data[x+1]) * g_factor);
		if (d < 0) { d = 0; }
		data[x+1] = d;
		d = (int) 255-((255-data[x+2]) * b_factor);
		if (d < 0) { d = 0; }
		data[x+2] = d;
	}

	/* ------------------ COLOR ENHANCE ------------------ */


	for (x = 0; x < (size * 3); x += 3)
	{
		r = data[x+0]; g = data[x+1]; b = data[x+2];
		d = (int) (r + 2*g + b) / 4.;
		if ( r > d )
			r = r + (int) ((r - d) * (255-r)/(256-d) * saturation);
		else 
			r = r + (int) ((r - d) * (255-d)/(256-r) * saturation);
		if (g > d)
			g = g + (int) ((g - d) * (255-g)/(256-d) * saturation);
		else 
			g = g + (int) ((g - d) * (255-d)/(256-g) * saturation);
		if (b > d)
			b = b + (int) ((b - d) * (255-b)/(256-d) * saturation);
		else 
			b = b + (int) ((b - d) * (255-d)/(256-b) * saturation);

		if (r < 0) { r = 0; }
		if (r > 255) { r = 255; }
		data[x+0] = r;
		if (g < 0) { g = 0; }
		if (g > 255) { g = 255; }
		data[x+1] = g;
		if (b < 0) { b = 0; }
		if (b > 255) { b = 255; }
		data[x+2] = b;
	}

	
	return 0;
}
コード例 #5
0
ファイル: jamcam.c プロジェクト: CastorGemini/libgphoto2
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 *raw, *ppm;
	unsigned char gtable[256];
	char *ptr;
	int size = 0, n = 0;
	int width, height;
	struct jamcam_file *jc_file;

	GP_DEBUG ("* camera_file_get");
	GP_DEBUG ("*** folder: %s", folder);
	GP_DEBUG ("*** filename: %s",filename);
	GP_DEBUG ("*** type: %d", type);

	CHECK (n = gp_filesystem_number (camera->fs, folder,
					 filename, context));

	if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
		return (GP_ERROR_CANCEL);

	raw = malloc(640*480 * 3);
	ppm = malloc(640*480 * 3 + 200);
	
	switch (type) {
	case GP_FILE_TYPE_PREVIEW:

		CHECK_free (jamcam_request_thumbnail (camera, file, raw, &size, n, context));


		width = 80;
		height = 60;

		sprintf( ppm,
			"P6\n"
			"# CREATOR: gphoto2, jamcam library\n"
			"%d %d\n"
			"255\n", width, height );

		ptr = ppm + strlen( ppm );

		size = strlen( ppm ) + ( height * width * 3 );

		gp_bayer_decode(raw, width, height, ptr, BAYER_TILE_GBRG );
		gp_gamma_fill_table( gtable, 0.5 );
		gp_gamma_correct_single( gtable, ptr, height * width );

		CHECK_free (gp_file_set_mime_type (file, GP_MIME_PPM));
		CHECK_free (gp_file_append (file, ppm, size));
		break;

	case GP_FILE_TYPE_NORMAL:
		CHECK_free (jamcam_request_image (camera, file, raw, &size, n, context));

		jc_file = jamcam_file_info (camera, n);

		sprintf( ppm,
			"P6\n"
			"# CREATOR: gphoto2, jamcam library\n"
			"%d %d\n"
			"255\n", jc_file->width, jc_file->height );

		ptr = ppm + strlen( ppm );

		size = strlen( ppm ) + ( jc_file->width * jc_file->height * 3 );

		gp_bayer_decode( raw, jc_file->width, jc_file->height, ptr,
			BAYER_TILE_GBRG );
		gp_gamma_fill_table( gtable, 0.5 );
		gp_gamma_correct_single( gtable, ptr, jc_file->width * jc_file->height );

		CHECK_free (gp_file_set_mime_type (file, GP_MIME_PPM));
		CHECK_free (gp_file_append (file, ppm, size));
		break;

	case GP_FILE_TYPE_RAW:
		CHECK_free (jamcam_request_image (camera, file, raw, &size, n, context));
		CHECK_free (gp_file_set_mime_type (file, GP_MIME_RAW));
		CHECK_free (gp_file_append (file, raw, size));
		break;
	default:
		free(raw); free(ppm);
		return (GP_ERROR_NOT_SUPPORTED);
	}
	free(raw); free(ppm);
	return (GP_OK);
}
コード例 #6
0
int main(int argc, char *argv[])
{
	
	image_info *info;


	int i;
	BYTE *bufp;
	BYTE *ppm, *ptr;
	FILE *fp_src, *fp_dest;
	char *dest;
	BYTE invert=0;
	BYTE qvga = 0;
	int size;
	float gamma_factor;
	BYTE gtable[256];
	int b;
	BYTE *buf;
	BYTE *buf2;
	int WIDTH=176, HEIGHT=144;
	BYTE outdoors;
        GtkWidget *window;
	GtkWidget *image;
	GtkWidget *event_box;
	int current = 1;
	int offset_correct = 0;

	if ( !(argc > 1) ){
		printf("Syntax: show_sonix_raw sourcefile, or \n");
		printf("Syntax: show_sonix_raw -useoffset sourcefile, or \n");
		printf("Syntax: show_sonix_raw -useoffset -invert sourcefile\n");
		return 0;
	}

	if ((strcmp(argv[current], "-qvga") == 0) && (current+1 < argc)) 
	{ 
		qvga = 1;
		offset_correct=8;
		current += 1;
		if (argc != 3) {
			printf("Syntax: show_sonix_raw -qvga sourcefile\n");
			return 0;
		}
	}


	if ( !(argc > 2) && (strcmp(argv[current], "-useoffset") == 0) )
	{
		printf("Syntax: show_sonix_raw sourcefile, or \n");
		printf("Syntax: show_sonix_raw -useoffset sourcefile \n");
		printf("Syntax: show_sonix_raw -useoffset -invert sourcefile\n");
		return 0;
	}

		printf("argc=%i\n", argc);


	if ((strcmp(argv[current], "-useoffset") == 0) && (current+1 < argc)) {
		offset_correct = 8;
		current += 1;
		printf("useoffset option used\n");
		printf("current=%i\n", current);
		if ( !(argc > 2) || !(argc < 5) ){
			printf("Syntax: show_sonix_raw sourcefile, or \n");
			printf("Syntax: show_sonix_raw -useoffset sourcefile, or \n");
			printf("Syntax: show_sonix_raw -useoffset -invert sourcefile, or\n");
			printf("Syntax: show_sonix_raw -qvga sourcefile\n");
			return 0;
		}
	}

	if ( !(argc > 3) && (strcmp(argv[current], "-invert") == 0) )
	{
		printf("Syntax: show_sonix_raw sourcefile, or \n");
		printf("Syntax: show_sonix_raw -useoffset sourcefile, or \n");
		printf("Syntax: show_sonix_raw -useoffset -invert sourcefile\n");
		return 0;
	}

	if ((strcmp(argv[current], "-invert") == 0) && (current+1 < argc)) {
		invert = 1;
		current += 1;
		printf("invert option used\n");
		printf("current=%i\n", current);
		if ( !(argc > 3) || !(argc < 5) ){
			printf("Syntax: show_sonix_raw sourcefile, or \n");
			printf("Syntax: show_sonix_raw -useoffset sourcefile, or \n");
			printf("Syntax: show_sonix_raw -useoffset -invert sourcefile \n");
			return 0;
		}

	}

	printf("Options: offset=%i invert=%i\n", offset_correct, invert);


	fprintf (stderr, "Name of source file is %s\n", argv[current]);
	
	/* input file is raw_(some characters).raw, so, first thing, we find 
	 * the "." in the name.
	 */

	dest = malloc(strlen(argv[current]));
	if (!dest){
		free(dest);
		return -1;
	}

	if ((!strchr(argv[current], 0x2e))|| (strncmp(argv[current], "raw", 3))) {
		fprintf (stderr, "Source file appears not to be a gphoto2 raw file.\n");
		fprintf (stderr, "Its name should begin with raw_ and end with .raw\n");		
		fprintf (stderr, "Exiting.\n");
		return 0; 
	}

	i = strchr(argv[current], 0x2e) - argv[current];

	/* and throw away the period (to avoid clobbering any finished images
	 * from gphoto2 which are in the same directory) and throw away the 
	 * suffix.
	 */

	strncpy(dest, argv[current] + 4, i - 4);
	/* then affix "ppm" as a suffix (no preceding period) */
	strcat (dest, "ppm");
	fprintf (stderr, "Destination file will be called %s\n", dest);
	/* now open the raw file */
	if ( (fp_src = fopen(argv[current], "rb") ) == NULL )
	{
		fprintf (stderr, "Error opening source file.\n");
		return 0;
	}
	/* get the size of the raw file and assign that size to "b" */    
	fseek(fp_src, 0, 2);
	b = ftell(fp_src);
	fseek(fp_src, 0, 0);

	buf = malloc(b);
	if (!buf) return -1;

	/* read the raw file to "buf", and close it */
	fread (buf, 1, b, fp_src);
	fclose (fp_src);

	info = malloc(512);
	if (!info) { free(info); return -1; }


	get_image_info( info, buf, b, qvga);

	/* If there is a header, then we print it as debug output, then 
	 * move past it, to the data. 
	 */
	bufp = buf+offset_correct;
	/* show header */
	for (i = 0; i < HEADER_LEN; i++) {
		fprintf(stderr, " %02X", buf[i]);
	}
	fprintf(stderr, "\n");

	WIDTH = info->width;
	HEIGHT = info->height;
	outdoors = info->outdoors;
	gamma_factor = info->gamma;
	gp_gamma_fill_table(gtable, gamma_factor);
	buf2 = malloc(WIDTH * HEIGHT+256);
	if (!buf2) {
		free (buf2);
		return -1;
	}
	if((offset_correct)&&!(qvga)) {
		info->reverse = 1;
		info->bayer = BAYER_TILE_BGGR;
	}
	if (info->compression) { /* non-zero if compression in use */
		sonix_decode(buf2, bufp, WIDTH,HEIGHT);	
	 } else {
		memcpy(buf2, bufp, WIDTH*HEIGHT);
	}
	free(buf);
	if (invert)
		reverse_bytes(buf2, WIDTH*HEIGHT);
	ppm = malloc (WIDTH * HEIGHT * 3 + 256); /* Data + header */
	if (!ppm) {
		free (buf2);
		return 0;
	}

	memset (ppm, 0, WIDTH * HEIGHT * 3 + 256);

	sprintf ((char *)ppm,
        	"P6\n"
        	"#CREATOR: My_decoder\n"
        	"%d %d\n"
        	"255\n", WIDTH, HEIGHT);

        ptr = ppm + strlen ((char *)ppm);
        size = strlen ((char *)ppm) + (WIDTH * HEIGHT * 3);
	gp_bayer_decode(buf2, WIDTH, HEIGHT, ptr, info->bayer);
	free(buf2);
        white_balance(ptr, WIDTH * HEIGHT, 1.2);

	if ( (fp_dest = fopen(dest, "wb") ) == NULL )
	{
		fprintf (stderr, "Error opening dest file.\n");
		return 0;
	}
	fwrite(ppm, 1, size, fp_dest);
	fclose (fp_dest);
	free (ppm);

	/* The file has been saved. The GUI effects follow now. */
        gtk_init (&argc, &argv);
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


	event_box = gtk_event_box_new();
	gtk_container_add(GTK_CONTAINER (window), event_box);
	gtk_widget_show(event_box);

	/* This lets the Window Manager to close the window _and_ sets up 
	 * this program to exit when the window is closed. 
	 */

        g_signal_connect (G_OBJECT (window), "delete_event",
                          G_CALLBACK (delete_event), NULL);
	/* This displays the image file. */
	image = gtk_image_new_from_file(dest);
	gtk_container_add(GTK_CONTAINER(event_box), image);
	gtk_widget_show (image);
        gtk_widget_show (window);
        gtk_main ();
	free(info);
	free(dest);
	return 0;
}
コード例 #7
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;
}
コード例 #8
0
ファイル: library.c プロジェクト: ryanstout/libgphoto2
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;
}
コード例 #9
0
ファイル: library.c プロジェクト: Dvizhenka/libgphoto2
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;
}
コード例 #10
0
ファイル: library.c プロジェクト: Dvizhenka/libgphoto2
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;
}