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); }
/* 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; }
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); }
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; }
int jd11_get_image_full( Camera *camera, CameraFile*file, int nr, int raw, GPContext *context ) { unsigned char *s,*uncomp[3],**imagebufs; int ret,sizes[3]; unsigned char *data; int h; ret = serial_image_reader(camera,file,nr,&imagebufs,sizes, context); if (ret!=GP_OK) return ret; uncomp[0] = malloc(320*480); uncomp[1] = malloc(320*480/2); uncomp[2] = malloc(320*480/2); if (sizes[0]!=115200) { picture_decomp_v1(imagebufs[0],uncomp[0],320,480); picture_decomp_v1(imagebufs[1],uncomp[1],320,480/2); picture_decomp_v1(imagebufs[2],uncomp[2],320,480/2); } else { picture_decomp_v2(imagebufs[0],uncomp[0],320,480); picture_decomp_v2(imagebufs[1],uncomp[1],320,480/2); picture_decomp_v2(imagebufs[2],uncomp[2],320,480/2); } gp_file_append(file, IMGHEADER, strlen(IMGHEADER)); data = malloc(640*480*3); if (!raw) { unsigned char *bayerpre; s = bayerpre = malloc(640*480); /* note that picture is upside down and left<->right mirrored */ for (h=480;h--;) { int w; for (w=320;w--;) { if (h&1) { /* G B G B G B G B G */ *s++ = uncomp[2][(h/2)*320+w]; *s++ = uncomp[0][h*320+w]; } else { /* R G R G R G R G R */ *s++ = uncomp[0][h*320+w]; *s++ = uncomp[1][(h/2)*320+w]; } } } gp_bayer_decode(bayerpre,640,480,data,BAYER_TILE_RGGB); free(bayerpre); } else { s=data; for (h=480;h--;) { /* upside down */ int w; for (w=640;w--;) { /* right to left */ /* and images are in green red blue */ *s++=uncomp[1][(h/2)*320+(w/2)]; *s++=uncomp[0][h*320+(w/2)]; *s++=uncomp[2][(h/2)*320+(w/2)]; } } } free(uncomp[0]);free(uncomp[1]);free(uncomp[2]); free(imagebufs[0]);free(imagebufs[1]);free(imagebufs[2]);free(imagebufs); gp_file_append(file, (char*)data, 640*480*3); 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; /* 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 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; }