2012-06-27 03:57:18 +04:00
|
|
|
/**
|
2012-10-09 07:02:04 +04:00
|
|
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
2012-06-27 03:57:18 +04:00
|
|
|
* Compressed jpeg
|
|
|
|
*
|
|
|
|
* Copyright 2012 Jay Sorg <jay.sorg@gmail.com>
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2022-02-16 13:20:38 +03:00
|
|
|
#include <freerdp/config.h>
|
2012-08-15 01:09:01 +04:00
|
|
|
|
2013-03-22 00:45:25 +04:00
|
|
|
#include <winpr/stream.h>
|
2012-10-19 06:05:06 +04:00
|
|
|
|
2012-06-27 03:57:18 +04:00
|
|
|
#include <freerdp/codec/color.h>
|
|
|
|
|
2012-10-19 06:05:06 +04:00
|
|
|
#include <freerdp/codec/jpeg.h>
|
|
|
|
|
2012-07-25 05:26:24 +04:00
|
|
|
#ifdef WITH_JPEG
|
|
|
|
|
2012-09-23 23:42:46 +04:00
|
|
|
#define XMD_H
|
|
|
|
|
2012-06-27 03:57:18 +04:00
|
|
|
#include <jpeglib.h>
|
|
|
|
|
|
|
|
struct mydata_decomp
|
|
|
|
{
|
|
|
|
char* data;
|
|
|
|
int data_bytes;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void my_init_source(j_decompress_ptr cinfo)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2015-09-07 14:54:41 +03:00
|
|
|
static boolean my_fill_input_buffer(j_decompress_ptr cinfo)
|
2012-06-27 03:57:18 +04:00
|
|
|
{
|
|
|
|
struct mydata_decomp* md;
|
|
|
|
|
|
|
|
md = (struct mydata_decomp*)(cinfo->client_data);
|
|
|
|
cinfo->src->next_input_byte = (unsigned char*)(md->data);
|
|
|
|
cinfo->src->bytes_in_buffer = md->data_bytes;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void my_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2015-09-07 14:54:41 +03:00
|
|
|
static boolean my_resync_to_restart(j_decompress_ptr cinfo, int desired)
|
2012-06-27 03:57:18 +04:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void my_term_source(j_decompress_ptr cinfo)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2019-11-06 17:24:51 +03:00
|
|
|
static int do_decompress(char* comp_data, int comp_data_bytes, int* width, int* height, int* bpp,
|
|
|
|
char* decomp_data, int* decomp_data_bytes)
|
2012-06-27 03:57:18 +04:00
|
|
|
{
|
2022-10-13 17:25:36 +03:00
|
|
|
struct jpeg_decompress_struct cinfo = { 0 };
|
2012-06-27 03:57:18 +04:00
|
|
|
struct jpeg_error_mgr jerr;
|
2022-10-13 17:25:36 +03:00
|
|
|
struct jpeg_source_mgr src_mgr = { 0 };
|
|
|
|
struct mydata_decomp md = { 0 };
|
|
|
|
JSAMPROW row_pointer[1] = { 0 };
|
2012-06-27 03:57:18 +04:00
|
|
|
|
|
|
|
cinfo.err = jpeg_std_error(&jerr);
|
|
|
|
jpeg_create_decompress(&cinfo);
|
|
|
|
|
|
|
|
cinfo.src = &src_mgr;
|
|
|
|
src_mgr.init_source = my_init_source;
|
|
|
|
src_mgr.fill_input_buffer = my_fill_input_buffer;
|
|
|
|
src_mgr.skip_input_data = my_skip_input_data;
|
|
|
|
src_mgr.resync_to_restart = my_resync_to_restart;
|
|
|
|
src_mgr.term_source = my_term_source;
|
|
|
|
|
|
|
|
md.data = comp_data;
|
|
|
|
md.data_bytes = comp_data_bytes;
|
|
|
|
cinfo.client_data = &md;
|
|
|
|
|
|
|
|
jpeg_read_header(&cinfo, 1);
|
|
|
|
|
|
|
|
cinfo.out_color_space = JCS_RGB;
|
|
|
|
|
|
|
|
*width = cinfo.image_width;
|
|
|
|
*height = cinfo.image_height;
|
|
|
|
*bpp = cinfo.num_components * 8;
|
|
|
|
|
|
|
|
jpeg_start_decompress(&cinfo);
|
|
|
|
|
2019-11-06 17:24:51 +03:00
|
|
|
while (cinfo.output_scanline < cinfo.image_height)
|
2012-06-27 03:57:18 +04:00
|
|
|
{
|
2019-11-06 17:24:51 +03:00
|
|
|
row_pointer[0] = (JSAMPROW)decomp_data;
|
2012-06-27 03:57:18 +04:00
|
|
|
jpeg_read_scanlines(&cinfo, row_pointer, 1);
|
|
|
|
decomp_data += cinfo.image_width * cinfo.num_components;
|
|
|
|
}
|
2019-11-06 17:24:51 +03:00
|
|
|
*decomp_data_bytes = cinfo.output_width * cinfo.output_height * cinfo.num_components;
|
2012-06-27 03:57:18 +04:00
|
|
|
jpeg_finish_decompress(&cinfo);
|
|
|
|
jpeg_destroy_decompress(&cinfo);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* jpeg decompress */
|
2012-10-19 06:05:06 +04:00
|
|
|
BOOL jpeg_decompress(BYTE* input, BYTE* output, int width, int height, int size, int bpp)
|
2012-06-27 03:57:18 +04:00
|
|
|
{
|
|
|
|
int lwidth;
|
|
|
|
int lheight;
|
|
|
|
int lbpp;
|
|
|
|
int ldecomp_data_bytes;
|
|
|
|
|
|
|
|
if (bpp != 24)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2019-11-06 17:24:51 +03:00
|
|
|
if (do_decompress((char*)input, size, &lwidth, &lheight, &lbpp, (char*)output,
|
|
|
|
&ldecomp_data_bytes) != 0)
|
2012-06-27 03:57:18 +04:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (lwidth != width || lheight != height || lbpp != bpp)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2012-07-25 05:26:24 +04:00
|
|
|
|
2012-07-26 22:15:41 +04:00
|
|
|
#else
|
|
|
|
|
2012-10-19 06:05:06 +04:00
|
|
|
BOOL jpeg_decompress(BYTE* input, BYTE* output, int width, int height, int size, int bpp)
|
2012-07-26 22:15:41 +04:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-07-25 05:26:24 +04:00
|
|
|
#endif
|