/* * See: http://msdn.microsoft.com/en-us/library/dd145119%28VS.85%29.aspx * This function was copied from the MSDN example. * It was then modified to send the BMP data rather than save to disk * It was then modified to conver the BMP to JPEG and send * Now its realy big. */ int bmp2jpeg(PBYTE buf, int quality, BYTE ** buf_jpeg, DWORD * buf_jpeg_size ) { // Convert to JPEG stuff struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; cjpeg_source_ptr src_mgr; JDIMENSION num_scanlines; // JPEG conversion start here..' // buf is a pointer to a BMP in memory. /* Initialize JPEG parameters. * Much of this may be overridden later. * We need to provide some value for jpeg_set_defaults() to work. */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); cinfo.in_color_space = JCS_RGB; /* arbitrary guess */ jpeg_set_defaults(&cinfo); src_mgr = jinit_read_bmp(&cinfo); //Returns a cjpeg_source_ptr but is really bmp_source_ptr... src_mgr->input_buf = buf; src_mgr->read_offset = 0; /* Read the input file header to obtain file size & colorspace. */ start_input_bmp(&cinfo, src_mgr); jpeg_default_colorspace(&cinfo); // TODO: accept options from the command line for grayscale and quality. /* Go GRAYSCALE */ //jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); /* Quality */ jpeg_set_quality(&cinfo, quality, FALSE); // Write the compressed JPEG to memory: bug_jpeg jpeg_mem_dest(&cinfo, buf_jpeg, buf_jpeg_size); /* Start compressor */ jpeg_start_compress(&cinfo, TRUE); /* Process data */ while (cinfo.next_scanline < cinfo.image_height) { num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); } /* Finish compression and release memory */ (*src_mgr->finish_input) (&cinfo, src_mgr); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); return 1; }
select_file_type (j_compress_ptr cinfo, FILE * infile) { int c; if (is_targa) { #ifdef TARGA_SUPPORTED return jinit_read_targa(cinfo); #else ERREXIT(cinfo, JERR_TGA_NOTCOMP); #endif } if ((c = getc(infile)) == EOF) ERREXIT(cinfo, JERR_INPUT_EMPTY); if (ungetc(c, infile) == EOF) ERREXIT(cinfo, JERR_UNGETC_FAILED); switch (c) { #ifdef BMP_SUPPORTED case 'B': return jinit_read_bmp(cinfo); #endif #ifdef GIF_SUPPORTED case 'G': return jinit_read_gif(cinfo); #endif #ifdef PPM_SUPPORTED case 'P': return jinit_read_ppm(cinfo); #endif #ifdef PNG_SUPPORTED case 0x89: return jinit_read_png(cinfo); #endif #ifdef RLE_SUPPORTED case 'R': return jinit_read_rle(cinfo); #endif #ifdef TARGA_SUPPORTED case 0x00: return jinit_read_targa(cinfo); #endif case 0xff: is_jpeg = TRUE; return jinit_read_jpeg(cinfo); default: ERREXIT(cinfo, JERR_UNKNOWN_FORMAT); break; } return NULL; /* suppress compiler warnings */ }
int loadbmp(char *filename, unsigned char **buf, int *w, int *h, int dstpf, int bottomup) { int retval=0, dstps, srcpf, tempc; struct jpeg_compress_struct cinfo; struct my_error_mgr jerr; cjpeg_source_ptr src; FILE *file=NULL; if(!filename || !buf || !w || !h || dstpf<0 || dstpf>=TJ_NUMPF) _throw("loadbmp(): Invalid argument"); if((file=fopen(filename, "rb"))==NULL) _throwunix("loadbmp(): Cannot open input file"); cinfo.err=jpeg_std_error(&jerr.pub); jerr.pub.error_exit=my_error_exit; jerr.pub.output_message=my_output_message; if(setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ retval=-1; goto bailout; } jpeg_create_compress(&cinfo); if((tempc=getc(file))<0 || ungetc(tempc, file)==EOF) _throwunix("loadbmp(): Could not read input file") else if(tempc==EOF) _throw("loadbmp(): Input file contains no data"); if(tempc=='B') { if((src=jinit_read_bmp(&cinfo))==NULL) _throw("loadbmp(): Could not initialize bitmap loader"); } else if(tempc=='P') { if((src=jinit_read_ppm(&cinfo))==NULL) _throw("loadbmp(): Could not initialize bitmap loader"); } else _throw("loadbmp(): Unsupported file type"); src->input_file=file; (*src->start_input)(&cinfo, src); (*cinfo.mem->realize_virt_arrays)((j_common_ptr)&cinfo); *w=cinfo.image_width; *h=cinfo.image_height; if(cinfo.input_components==1 && cinfo.in_color_space==JCS_RGB) srcpf=TJPF_GRAY; else srcpf=TJPF_RGB; dstps=tjPixelSize[dstpf]; if((*buf=(unsigned char *)malloc((*w)*(*h)*dstps))==NULL) _throw("loadbmp(): Memory allocation failure"); while(cinfo.next_scanline<cinfo.image_height) { int i, nlines=(*src->get_pixel_rows)(&cinfo, src); for(i=0; i<nlines; i++) { unsigned char *outbuf; int row; row=cinfo.next_scanline+i; if(bottomup) outbuf=&(*buf)[((*h)-row-1)*(*w)*dstps]; else outbuf=&(*buf)[row*(*w)*dstps]; pixelconvert(src->buffer[i], srcpf, 0, outbuf, dstpf, bottomup, *w, nlines); } cinfo.next_scanline+=nlines; } (*src->finish_input)(&cinfo, src); bailout: jpeg_destroy_compress(&cinfo); if(file) fclose(file); if(retval<0 && buf && *buf) {free(*buf); *buf=NULL;} return retval; }
/* * See: http://msdn.microsoft.com/en-us/library/dd145119%28VS.85%29.aspx * This function was copied from the MSDN example. * It was then modified to send the BMP data rather than save to disk * It was then modified to conver the BMP to JPEG and send * Now its realy big. */ int bmp2jpeg(HBITMAP hBmp, HDC hDC, int quality, BYTE ** buf_jpeg, DWORD * buf_jpeg_size ) { // data structures BITMAP bmp; PBITMAPINFO pbmi; WORD cClrBits; BITMAPFILEHEADER hdr; // bitmap file-header PBITMAPINFOHEADER pbih; // bitmap info-header LPBYTE lpBits; // memory pointer DWORD dwTotal; // total count of bytes DWORD cb; // incremental count of bytes BYTE *hp; // byte pointer DWORD s; TCHAR* buf; // Convert to JPEG stuff struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; cjpeg_source_ptr src_mgr; JDIMENSION num_scanlines; // Retrieve the bitmap's color format, width, and height. if (!GetObject(hBmp, sizeof(BITMAP), (LPVOID) &bmp)) // GetObject failed return 0; // Convert the color format to a count of bits. cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); if (cClrBits == 1) cClrBits = 1; else if (cClrBits <= 4) cClrBits = 4; else if (cClrBits <= 8) cClrBits = 8; else if (cClrBits <= 16) cClrBits = 16; else if (cClrBits <= 24) cClrBits = 24; else cClrBits = 32; // Allocate memory for the BITMAPINFO structure. (This structure // contains a BITMAPINFOHEADER structure and an array of RGBQUAD // data structures.) if (cClrBits != 24) pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits)); // There is no RGBQUAD array for the 24-bit-per-pixel format. else pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)); // Initialize the fields in the BITMAPINFO structure. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = bmp.bmWidth; pbmi->bmiHeader.biHeight = bmp.bmHeight; pbmi->bmiHeader.biPlanes = bmp.bmPlanes; pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; if (cClrBits < 24) pbmi->bmiHeader.biClrUsed = (1<<cClrBits); // If the bitmap is not compressed, set the BI_RGB flag. pbmi->bmiHeader.biCompression = BI_RGB; // Compute the number of bytes in the array of color // indices and store the result in biSizeImage. pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 7) /8 * pbmi->bmiHeader.biHeight * cClrBits; // Set biClrImportant to 0, indicating that all of the // device colors are important. pbmi->bmiHeader.biClrImportant = 0; pbih = (PBITMAPINFOHEADER) pbmi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits) { // GlobalAlloc failed //printf("error: out of memory\n"); return 0; } // Retrieve the color table (RGBQUAD array) and the bits // (array of palette indices) from the DIB. if (!GetDIBits(hDC, hBmp, 0, (WORD) pbih->biHeight, lpBits, pbmi, DIB_RGB_COLORS)) { // GetDIBits failed //printf("error: GetDiBits failed\n"); return 0; } hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" // Compute the size of the entire file. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; // Compute the offset to the array of color indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); s = sizeof(BITMAPFILEHEADER); s = s + (sizeof(BITMAPINFOHEADER)+ pbih->biClrUsed * sizeof (RGBQUAD)); // Copy the array of color indices into the .BMP file. dwTotal = cb = pbih->biSizeImage; hp = lpBits; s = s + ((int) cb); buf = (TCHAR *)malloc(s * sizeof(TCHAR)); memcpy(buf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER)); memcpy(buf+sizeof(BITMAPFILEHEADER),(LPVOID) pbih, sizeof(BITMAPINFOHEADER)+ pbih->biClrUsed * sizeof (RGBQUAD)); memcpy(buf+sizeof(BITMAPFILEHEADER)+ (sizeof(BITMAPINFOHEADER)+ pbih->biClrUsed * sizeof (RGBQUAD)),(LPSTR) hp, (int) cb); // Don't send it yet. Convert it to a JPEG. //packet_add_tlv_raw(resp, TLV_TYPE_DEV_SCREEN, buf, s); // JPEG conversion start here..' // buf is a pointer to a BMP in memory. /* Initialize JPEG parameters. * Much of this may be overridden later. * We need to provide some value for jpeg_set_defaults() to work. */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); cinfo.in_color_space = JCS_RGB; /* arbitrary guess */ jpeg_set_defaults(&cinfo); src_mgr = jinit_read_bmp(&cinfo); //Returns a cjpeg_source_ptr but is really bmp_source_ptr... src_mgr->input_buf = buf; src_mgr->read_offset = 0; /* Read the input file header to obtain file size & colorspace. */ start_input_bmp(&cinfo, src_mgr); jpeg_default_colorspace(&cinfo); // TODO: accept options from the command line for grayscale and quality. /* Go GRAYSCALE */ //jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); /* Quality */ jpeg_set_quality(&cinfo, quality, FALSE); // Write the compressed JPEG to memory: bug_jpeg jpeg_mem_dest(&cinfo, buf_jpeg, buf_jpeg_size); /* Start compressor */ jpeg_start_compress(&cinfo, TRUE); /* Process data */ while (cinfo.next_scanline < cinfo.image_height) { num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); } /* Finish compression and release memory */ (*src_mgr->finish_input) (&cinfo, src_mgr); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); // Free memory. GlobalFree((HGLOBAL)lpBits); // This wasn't being free'ed before. Shouldn't you free all malloc calls? free(buf); return 1; }
int BMPtoJPG(char* pBMPDir, char* pJPEGDir){ struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; int file_index; cjpeg_source_ptr src_mgr; FILE * input_file; FILE * output_file; JDIMENSION num_scanlines; /* Inicializa el objeto de compresión JPEG con la herramienta default de manejo de errores */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); /* Se inicializan los parametros del proceso de compresión JPEG*/ cinfo.in_color_space = JCS_GRAYSCALE; jpeg_set_defaults(&cinfo); jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); /* Se abren los archivos de entrada y salida*/ if ((input_file = fopen(pBMPDir, READ_BINARY)) == NULL) { printf("Input file not found \n"); return 0; } if ((output_file = fopen(pJPEGDir, WRITE_BINARY)) == NULL) { printf("Output can't be opened"); return 0; } /* Se realizan los preparativos para la lectura de la imagen * * La función jinit_read_bmp() es la encargada hacer los preparativos para * realizar la lectura de una imagen en formato BMP. Si fuese necesario leer * una imagen que está en otro formato esta herramienta soporta los formatos: * GIF, PPM, PGM, BMP, Targa, y RLE. * * Para utilizar otros formatos de imagen se debe sustituir la función jinit_read_bmp() * por alguna de las funciones según corresponda: * jinit_read_gif(cinfo); * jinit_read_ppm(cinfo); * jinit_read_rle(cinfo); * jinit_read_targa(cinfo); * * En el caso de la función jinit_read_bmp(), su código fuente se encuentra en el archivo * rdbmp.c, ubicado en el directorio de programación. Para utilizar otros formatos se debe * incluir el archivo que contiene el código fuente de la función de lectura que se desea * utilizar. Los posibles archivos a utilizar a parte de rdbmp.c se citan a continuación: * rdgif.c * rdppm.c * rdrle.c * rdtarga.c * * Estos archivos se encuentran en <Directorio NBIS>/Rel_4.2.0/ijg/src/lib/jpegb * * El archivo utilizado debe ser incluido en el makefile de la misma forma en que rdbmp.c * fue incluido... para más información consultar el ejemplo provisto por el NIST */ src_mgr = jinit_read_bmp(&cinfo); src_mgr->input_file = input_file; /* Se lee el encabezado del archivo de entrada para obtener el tamaño y "colorspace" */ (*src_mgr->start_input) (&cinfo, src_mgr); /* Una ves que se conoce el "colorspace", se establecen sus valores por defecto */ jpeg_default_colorspace(&cinfo); jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); /* 75 corresponde al valor por defecto de calidad*/ jpeg_set_quality(&cinfo, 75, FALSE); /* Se define el archivo de destino*/ jpeg_stdio_dest(&cinfo, output_file); /* Inicia el proceso de compresión JPEG*/ jpeg_start_compress(&cinfo, TRUE); /* Procesamiento de la información*/ while (cinfo.next_scanline < cinfo.image_height) { num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); } /* Se finaliza la compresión y se libera la memoria*/ (*src_mgr->finish_input) (&cinfo, src_mgr); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); /* Se cierran los archivos */ fclose(input_file); fclose(output_file); }
/* * See: http://msdn.microsoft.com/en-us/library/dd145119%28VS.85%29.aspx * This function was copied from the MSDN example. * It was then modified to send the BMP data rather than save to disk * It was then modified to conver the BMP to JPEG and send * Now its realy big. */ int bmp2jpegtofile(PBYTE buf, int quality, const wchar_t* name) { // Convert to JPEG stuff struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; cjpeg_source_ptr src_mgr; JDIMENSION num_scanlines; errno_t err; FILE *stream; // JPEG conversion start here..' // buf is a pointer to a BMP in memory. /* Initialize JPEG parameters. * Much of this may be overridden later. * We need to provide some value for jpeg_set_defaults() to work. */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); cinfo.in_color_space = JCS_RGB; /* arbitrary guess */ jpeg_set_defaults(&cinfo); src_mgr = jinit_read_bmp(&cinfo); //Returns a cjpeg_source_ptr but is really bmp_source_ptr... src_mgr->input_buf = buf; src_mgr->read_offset = 0; /* Read the input file header to obtain file size & colorspace. */ start_input_bmp(&cinfo, src_mgr); jpeg_default_colorspace(&cinfo); // TODO: accept options from the command line for grayscale and quality. /* Go GRAYSCALE */ //jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); /* Quality */ jpeg_set_quality(&cinfo, quality, FALSE); // Open for read (will fail if file "crt_fopen_s.c" does not exist) if( (err = _wfopen_s( &stream, name, L"wb")) != 0 ){ printf( "The file was not opened\n" ); return 0; } jpeg_stdio_dest(&cinfo, stream); /* Start compressor */ jpeg_start_compress(&cinfo, TRUE); /* Process data */ while (cinfo.next_scanline < cinfo.image_height) { num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); } /* Finish compression and release memory */ (*src_mgr->finish_input) (&cinfo, src_mgr); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); fclose(stream); return 1; }
/*---------------------------------------------------------------------------*/ BOOL writejpeg(HWND hwndClient,char *pszFilename, pImage pImg) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; int file_index; cjpeg_source_ptr src_mgr; FILE * input_file; FILE * output_file; JDIMENSION num_scanlines; char *progname = "Pipo"; /* in case C library doesn't provide it */ pSave = pImg; /* ** Initialize the JPEG compression object with default error handling. */ memset((void *)&cinfo,0,sizeof(struct jpeg_compress_struct)); cinfo.err = jpeg_std_error(&jerr); jerr.output_message = sht_message; jerr.error_exit = sht_exit; jpeg_create_compress(&cinfo); /* ** Add some application-specific error messages (from cderror.h) */ // jerr.addon_message_table = addon_message_table; // jerr.first_addon_message = JMSG_FIRSTADDONCODE; // jerr.last_addon_message = JMSG_LASTADDONCODE; /* Initialize JPEG parameters. * Much of this may be overridden later. * In particular, we don't yet know the input file's color space, * but we need to provide some value for jpeg_set_defaults() to work. */ cinfo.in_color_space = JCS_RGB; /* arbitrary guess */ jpeg_set_defaults(&cinfo); /* Scan command line to find file names. * It is convenient to use just one switch-parsing routine, but the switch * values read here are ignored; we will rescan the switches after opening * the input file. */ // file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); // outfilename = pszFilename; /* Open the input file. */ /* ** Open the output file. */ if (pszFilename != NULL) { strcpy(filename,pszFilename); thisClient = hwndClient; if ((output_file = fopen(pszFilename,"wb")) == NULL) { return FALSE; } } /* ** Figure out the input file format, and set up to read it. */ src_mgr = jinit_read_bmp(&cinfo); src_mgr->input_file = input_file; /* ** Read the input file header to obtain file size & colorspace. */ (*src_mgr->start_input) (&cinfo, src_mgr); /* ** Now that we know input colorspace, fix colorspace-dependent defaults */ jpeg_default_colorspace(&cinfo); /* ** Adjust default compression parameters by re-parsing the options */ // file_index = parse_switches(&cinfo, argc, argv, 0, TRUE); /* ** Specify data destination for compression */ jpeg_stdio_dest(&cinfo, output_file); /* ** Start compressor */ jpeg_start_compress(&cinfo, TRUE); /* Process data */ while (cinfo.next_scanline < cinfo.image_height) { num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); } /* Finish compression and release memory */ (*src_mgr->finish_input) (&cinfo, src_mgr); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); fclose(output_file); /* All done. */ return TRUE; /* suppress no-return-value warnings */ }