コード例 #1
0
int main(int argc, char *argv[])
{
	FILE *fin, *fout;
	uint16_t thumb[65536];
	uint8_t header[16];
	uint8_t jpeg_stripe[500000];
	uint8_t out[5000000];
	uint8_t jpeg_data[500000];
	int q, width, height;
	int thumbnail_width, thumbnail_height;
	char fname[256];
	char outname[256];
	struct jpeg_compress_struct cinfo;
	struct jpeg_decompress_struct dinfo;
	struct jpeg_error_mgr jcerr, jderr;
	JOCTET *jpeg_header = NULL;
	unsigned long jpeg_header_size = 0;
	int i, x, y, x1, y1, jpeg_data_size, jpeg_data_idx, eoi, size, ret;

	if (argc != 2) {
		printf("syntax: jl2005bcd_decompress (some raw file)\n");
		return 1;
	}

	fin = fopen(argv[1], "r");
	if(!fin) {
		printf("Error opening raw file. Exiting.\n");
		return 0;
	}

	if (!strchr(argv[1], 0x2e)) {
		fprintf(stderr,
			"\tIllegal input file.\n"
			"\tNo period in filename!\n"
			"\tExiting!\n");
		return 0;
	}
	i = strchr(argv[1], 0x2e) - argv[1];
	if (i < 4) {
		fprintf(stderr,
			"\tBasename of input file is too short!\n"
			"\tExiting!\n");
		return 0;
	}
	/* Finally, check whether the alleged input file really claims to be
	 * a gphoto2 raw file, at least by its name */
	if (strncmp("raw_", argv[1], 4)) {
		fprintf(stderr,
		"\tThe input does not even claim to be a raw file!\n"
		"\tExiting!\n");
		return 0;
	}
	/* To create the name(s) of the destination file(s), remove
	 * the prefix raw_ as the first step.
	 */

	strncpy(outname, argv[1] + 4, i - 4);
	strcat (outname, "r");
	fprintf (stderr, "Destination file will be called %s\n", outname);


	fread(header, 1, 16, fin);
	q = header[3] & 0x7f;
	height = header[4] * 8;
	width = header[5] * 8;
	printf("quality is %d\n", q);
	printf("size: %dx%d\n", width, height);
	switch (header[9]) {
	case 0xf0:
		thumbnail_width = 128;
		thumbnail_height = 120;
		break;
	case 0x60:
		thumbnail_width = 96;
		thumbnail_height = 64;
		break;
	default:
		thumbnail_width = 0;
		thumbnail_height = 0;
	}

	if(thumbnail_width) {
		sprintf(fname, "%s-thumb.ppm", outname);
		fout = fopen(fname, "w");
		if (!fin || !fout) {
			printf("still stupid!\n");
			return 1;
		}

		fread(thumb, 1, thumbnail_width * thumbnail_height * 2, fin);

		for (i = 0; i < thumbnail_width * thumbnail_height; i++) {
			thumb[i] = ntohs(thumb[i]);
			out[i * 3 + 0] = (thumb[i] & 0xf800) >> 8;
			out[i * 3 + 1] = (thumb[i] & 0x07e0) >> 3;
			out[i * 3 + 2] = (thumb[i] & 0x001f) << 3;
		}

		fprintf(fout, "P6\n%d %d\n255\n", thumbnail_width,
							thumbnail_height);
		fwrite(out, 1, thumbnail_width * thumbnail_height * 3, fout);
		fclose(fout);
	}
	/*
	 * And the fun begins, first of all create a dummy jpeg, which we use
	 * to get the headers from to feed to libjpeg when decompressing the
	 * stripes. This way we can use libjpeg's quant table handling
	 * (and built in default huffman tables).
	 */
	cinfo.err = jpeg_std_error (&jcerr);
	jpeg_create_compress (&cinfo);
	jpeg_mem_dest (&cinfo, &jpeg_header, &jpeg_header_size);
	cinfo.image_width = 16;
	cinfo.image_height = 16;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;
	jpeg_set_defaults (&cinfo);
	/* Make comp[0] (which will be green) 1x2 subsampled */
	cinfo.comp_info[0].h_samp_factor = 1;
	cinfo.comp_info[0].v_samp_factor = 2;
	/* Make comp[1] and [2] use huffman table and quanttable 0, as all
	 * components use luminance settings with the jl2005c/d/e */
	cinfo.comp_info[1].quant_tbl_no = 0;
	cinfo.comp_info[1].dc_tbl_no = 0;
	cinfo.comp_info[1].ac_tbl_no = 0;
	cinfo.comp_info[2].quant_tbl_no = 0;
	cinfo.comp_info[2].dc_tbl_no = 0;
	cinfo.comp_info[2].ac_tbl_no = 0;
	/* Apply the quality setting from the header */
	if (q <= 0)
		i = 5000;
	else if (q <= 50)
		i = 5000 / q;
	else if (q <= 100)
		i = 2 * (100 - q);
	else
		i = 0;
	jpeg_set_linear_quality(&cinfo, i, TRUE);

	jpeg_start_compress (&cinfo, TRUE);
	while( cinfo.next_scanline < cinfo.image_height ) {
		JOCTET row[16 * 3];
		JSAMPROW row_pointer[1] = { row };
		jpeg_write_scanlines (&cinfo, row_pointer, 1);
	}
	jpeg_finish_compress (&cinfo);
	jpeg_destroy_compress (&cinfo);

	JSAMPLE green[8 * 16];
	JSAMPLE red[8 * 8];
	JSAMPLE blue[8 * 8];
	JSAMPROW green_row_pointer[16];
	JSAMPROW red_row_pointer[8];
	JSAMPROW blue_row_pointer[8];

	for (i = 0; i < 16; i++)
		green_row_pointer[i] = green + i * 8;

	for (i = 0; i < 8; i++) {
		red_row_pointer[i] = red + i * 8;
		blue_row_pointer[i] = blue + i * 8;
	}

	JSAMPARRAY samp_image[3] = { green_row_pointer,
				     red_row_pointer,
				     blue_row_pointer };

	memcpy(jpeg_stripe, jpeg_header, JPEG_HEADER_SIZE);
	jpeg_stripe[JPEG_HEIGHT_OFFSET    ] = height >> 8;
	jpeg_stripe[JPEG_HEIGHT_OFFSET + 1] = height;
	jpeg_stripe[JPEG_HEIGHT_OFFSET + 2] = 0;
	jpeg_stripe[JPEG_HEIGHT_OFFSET + 3] = 8;
	free (jpeg_header);
	jpeg_data_size = fread(jpeg_data, 1, 500000, fin);
	jpeg_data_idx = 0;

	memset(out, 0, width * height * 3);

	dinfo.err = jpeg_std_error (&jderr);
	jpeg_create_decompress (&dinfo);
	for (x = 0; x < width; x += 16) {
		eoi = find_eoi(jpeg_data, jpeg_data_idx, jpeg_data_size);
		if (eoi < 0)
			return eoi;

		size = eoi - jpeg_data_idx;
		if ((JPEG_HEADER_SIZE + size) > sizeof(jpeg_stripe)) {
			printf("AAAIIIIII\n");
			return 1;
		}
		memcpy (jpeg_stripe + JPEG_HEADER_SIZE,
			jpeg_data + jpeg_data_idx, size);

		jpeg_mem_src (&dinfo, jpeg_stripe, JPEG_HEADER_SIZE + size);
		jpeg_read_header (&dinfo, TRUE);
		dinfo.raw_data_out = TRUE;
#if JPEG_LIB_VERSION >= 70
		dinfo.do_fancy_upsampling = FALSE;
#endif
		jpeg_start_decompress (&dinfo);
		for (y = 0; y < height; y += 16) {
			jpeg_read_raw_data (&dinfo, samp_image, 16);
			for (y1 = 0; y1 < 16; y1 += 2) {
				for (x1 = 0; x1 < 16; x1 += 2) {
					out[((y + y1 + 0) * width
							+ x + x1 + 0) * 3]
						= red[y1 * 4 + x1 / 2];
					out[((y + y1 + 0) * width
							+ x + x1 + 1) * 3 + 1]
						= green[y1 * 8 + x1 / 2];
					out[((y + y1 + 1) * width
							+ x + x1 + 0) * 3 + 1]
						= green[y1 * 8 + 8 + x1 / 2];
					out[((y + y1 + 1) * width
							+ x + x1 + 1) * 3 + 2]
						= blue[y1 * 4 + x1 / 2];
				}
			}
		}
		jpeg_finish_decompress (&dinfo);

		/* Set jpeg_data_idx for the next stripe */
		jpeg_data_idx = (jpeg_data_idx + size + 0x0f) & ~0x0f;
	}
	jpeg_destroy_decompress(&dinfo);

	ret = gp_ahd_interpolate(out, width, height, BAYER_TILE_BGGR);
	if (ret < 0) {
		printf("HEUH?\n");
		return ret;
	}
	white_balance (out, width*height, 1.6);
	sprintf(fname, "%s.ppm", outname);
	fout = fopen(fname, "w");
	if (!fout) {
		printf("stupid again?\n");
		return 1;
	}
	fprintf(fout, "P6\n%d %d\n255\n", width, height);
	fwrite(out, 1, width * height * 3, fout);
	fclose(fin);
	fclose(fout);
	return 0;
}
コード例 #2
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;
}