📄 save.c
字号:
#include <unistd.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <fcntl.h>#include <pthread.h>#include <gtk/gtk.h>#include <linux/types.h> #include <linux/videodev.h>#include <stdio.h>#include <jpeglib.h>#include <png.h>#include "gqcam.h"#include "frontend.h"#include "save.h"#include "time.h"void select_ok(GtkWidget *widget, struct Camera *camera){ gtk_entry_set_text(GTK_ENTRY(camera->save_struct.textbox), gtk_file_selection_get_filename(GTK_FILE_SELECTION (camera->save_struct.fileselect))); gtk_widget_destroy(camera->save_struct.fileselect); return;}void select_cancel(GtkWidget *widget, GdkEvent *event, gpointer data){ gtk_widget_destroy(GTK_WIDGET(widget)); return;}void file_select(GtkWidget *widget, struct Camera *camera){ // camera->saving = 1; camera->save_struct.fileselect = gtk_file_selection_new("Save Image"); gtk_file_selection_set_filename (GTK_FILE_SELECTION(camera->save_struct.fileselect), camera->savefileclean); gtk_widget_show(camera->save_struct.fileselect); gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (camera->save_struct.fileselect)->cancel_button), "clicked", (GtkSignalFunc) select_cancel, GTK_OBJECT (camera->save_struct.fileselect)); gtk_signal_connect(GTK_OBJECT (GTK_FILE_SELECTION (camera->save_struct.fileselect)->ok_button), "clicked", (GtkSignalFunc) select_ok, camera); return;}void save_ok(GtkWidget *widget, struct Camera *camera){ int ls=0, x, y; int i; int lines, pixels_per_line; FILE *outfile; unsigned char buff[3]; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; // pointer to JSAMPLE row(s) int row_stride; // physical row width in image buffer png_byte interlace; if(strlen(gtk_entry_get_text(GTK_ENTRY(camera->save_struct.textbox))) > 255){ errordialog("File name too long...\n"); return; } strcpy(camera->savefile, gtk_entry_get_text(GTK_ENTRY(camera->save_struct.textbox))); strcpy(camera->savefileclean, gtk_entry_get_text(GTK_ENTRY(camera->save_struct.textbox))); camera->save_struct.isinfo = 1; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(camera->save_struct.timebutton))) savefile_append_time(camera); switch (camera->savetype) { case PPM: if (GTK_TOGGLE_BUTTON(camera->page_ppm.radio_raw_ppm)->active){ camera->save_struct.format = RAW; } else if (GTK_TOGGLE_BUTTON(camera->page_ppm.radio_ascii_ppm)->active){ camera->save_struct.format = ASCII; } if (camera->saving) ppm_save(camera); break; case JPEG: camera->save_struct.quality = GTK_ADJUSTMENT(camera->page_jpeg.quality_adj_jpeg)->value; camera->save_struct.smoothness = GTK_ADJUSTMENT(camera->page_jpeg.smooth_adj_jpeg)->value; camera->save_struct.optimize = (GTK_TOGGLE_BUTTON(camera->page_jpeg.optimize_jpeg)->active)?1:0; if (camera->saving) jpeg_save(camera); break; case GIF: break; case PNG: if(GTK_TOGGLE_BUTTON(camera->page_png.interlace_png)->active) camera->save_struct.interlace = PNG_INTERLACE_ADAM7; else camera->save_struct.interlace = PNG_INTERLACE_NONE; camera->save_struct.compression = GTK_ADJUSTMENT(camera->page_png.compression_adj_png)->value; if (camera->saving) png_save(camera); break; } gtk_widget_destroy(widget->parent->parent->parent); pthread_mutex_lock( &camera->pref_mutex ); if( !camera->frozen ) pthread_mutex_unlock( &camera->freeze_mutex ); camera->saving = 0; pthread_mutex_unlock( &camera->pref_mutex ); return;}void png_save(struct Camera *camera){ FILE *fp; png_structp png_ptr; png_infop info_ptr; png_uint_32 k, height, width; png_bytep row_pointers[camera->vid_win.height]; /* open the file */ if(!strcmp(camera->savefile, "")) fp = stdout; else if(camera->savefile != NULL) fp = fopen(camera->savefile, "w"); if (fp == NULL){ errordialog("Error - Could not open file"); return; } /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also check that * the library version is compatible with the one used at compile time, * in case we are using dynamically linked libraries. REQUIRED. */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { errordialog("Error - could not create PNG"); fclose(fp); return; } /* Allocate/initialize the image information data. REQUIRED */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return; } /* Set error handling. REQUIRED if you aren't supplying your own * error hadnling functions in the png_create_write_struct() call. */ if (setjmp(png_ptr->jmpbuf)) { /* If we get here, we had a problem reading the file */ fclose(fp); png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return; } /* One of the following I/O initialization functions is REQUIRED */ /* set up the output control if you are using standard C streams */ png_init_io(png_ptr, fp); /* Set the image information here. Width and height are up to 2^31, * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED */ if(camera->greyscale) png_set_IHDR(png_ptr, info_ptr, camera->vid_win.width, camera->vid_win.height, 8, PNG_COLOR_TYPE_GRAY, camera->save_struct.interlace, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); else png_set_IHDR(png_ptr, info_ptr, camera->vid_win.width, camera->vid_win.height, 8, PNG_COLOR_TYPE_RGB, camera->save_struct.interlace, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_set_compression_level(png_ptr, camera->save_struct.compression); /* set the palette if there is one. REQUIRED for indexed-color images */ //palette = (png_colorp)png_malloc(png_ptr, 256 * sizeof (png_color)); /* ... set palette colors ... */ //png_set_PLTE(png_ptr, info_ptr, palette, 256); /* optional significant bit chunk */ /* if we are dealing with a grayscale image then */ //sig_bit.gray = true_bit_depth; /* otherwise, if we are dealing with a color image then */ //sig_bit.red = true_red_bit_depth; //sig_bit.green = true_green_bit_depth; //sig_bit.blue = true_blue_bit_depth; /* if the image has an alpha channel then */ //sig_bit.alpha = true_alpha_bit_depth; //png_set_sBIT(png_ptr, info_ptr, sig_bit); /* Optional gamma chunk is strongly suggested if you have any guess * as to the correct gamma of the image. */ //png_set_gAMA(png_ptr, info_ptr, gamma); /* Optionally write comments into the image *//* text_ptr[0].key = "Title"; text_ptr[0].text = "Mona Lisa"; text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE; text_ptr[1].key = "Author"; text_ptr[1].text = "Leonardo DaVinci"; text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE; text_ptr[2].key = "Description"; text_ptr[2].text = "<long text>"; text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt; png_set_text(png_ptr, info_ptr, text_ptr, 3);*/ /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ /* note that if sRGB is present the cHRM chunk must be ignored * on read and must be written in accordance with the sRGB profile */ /* Write the file header information. REQUIRED */ png_write_info(png_ptr, info_ptr); /* Once we write out the header, the compression type on the text * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again * at the end. */ /* set up the transformations you want. Note that these are * all optional. Only call them if you want them. */ /* invert monocrome pixels */ //png_set_invert_mono(png_ptr); /* Shift the pixels up to a legal bit depth and fill in * as appropriate to correctly scale the image. */ //png_set_shift(png_ptr, &sig_bit); /* pack pixels into bytes */ //png_set_packing(png_ptr); /* swap location of alpha bytes from ARGB to RGBA */ //png_set_swap_alpha(png_ptr); /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels). The second parameter is not used. */ //png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); /* flip BGR pixels to RGB */ //png_set_bgr(png_ptr); /* swap bytes of 16-bit files to most significant byte first */ //png_set_swap(png_ptr); /* swap bits of 1, 2, 4 bit packed pixel formats */ //png_set_packswap(png_ptr); /* turn on interlace handling if you are not using png_write_image() *//* if (interlacing) number_passes = png_set_interlace_handling(png_ptr); else number_passes = 1;*/ /* The easiest way to write the image (you may have a different memory * layout, however, so choose what fits your needs best). You need to * use the first method if you aren't handling interlacing yourself. *//* png_uint_32 k, height, width; png_byte image[height][width]; png_bytep row_pointers[height];*/ if (camera->greyscale) { for (k = 0; k < camera->vid_win.height; k++) row_pointers[k] = camera->pic + k*camera->vid_win.width; } else { for (k = 0; k < camera->vid_win.height; k++) row_pointers[k] = camera->pic + k*camera->vid_win.width*3; } /* One of the following output methods is REQUIRED */ png_write_image(png_ptr, row_pointers); /* You can write optional chunks like tEXt, zTXt, and tIME at the end * as well. */ /* It is REQUIRED to call this to finish writing the rest of the file */ png_write_end(png_ptr, info_ptr); /* if you malloced the palette, free it here */ free(info_ptr->palette); /* if you allocated any text comments, free them here */ /* clean up after the write, and free any memory allocated */ png_destroy_write_struct(&png_ptr, (png_infopp)NULL); /* close the file */ fclose(fp); /* that's it */ return;}void ppm_save(struct Camera *camera){ FILE *outfile; unsigned char buff[3]; int i; if(!strcmp(camera->savefile, "")) outfile = stdout; else if(camera->savefile != NULL) outfile = fopen(camera->savefile, "w"); if (outfile == NULL){ errordialog("Could not open file"); return; } /* Raw */ if (camera->save_struct.format == RAW){ fprintf (outfile, "P6\n%d %d\n%d\n", camera->vid_win.width, camera->vid_win.height, 255); if (camera->greyscale){ for (i = 0; i < camera->vid_win.width*camera->vid_win.height; i++){ buff[0] = camera->pic[i]; buff[1] = camera->pic[i]; buff[2] = camera->pic[i]; fwrite (buff, 1, 3, outfile); } } else { for (i = 0; i < camera->vid_win.width * camera->vid_win.height * 3; i++) { fputc(camera->pic[i], outfile); } } } /* Ascii */ else if (camera->save_struct.format == ASCII){ fprintf (outfile, "P3\n%d %d\n%d\n", camera->vid_win.width, camera->vid_win.height, 255); if (camera->greyscale) { for (i = 0; i < camera->vid_win.width*camera->vid_win.height; i++){ fprintf (outfile, "%03d %03d %03d\n", camera->pic[i], camera->pic[i], camera->pic[i]); } } else for (i = 0; i < camera->vid_win.width*camera->vid_win.height*3; i=i+3){ fprintf (outfile, "%03d %03d %03d\n", camera->pic[i], camera->pic[i+1], camera->pic[i+2]); } } fclose(outfile);}void jpeg_save(struct Camera *camera){ FILE *outfile; int ls=0, x, y; int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -