/* * 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; }
/* * 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; }
/* * 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; }