From 1eb88d4f5d5cb05d62be1d4a0c88c7399f7c0de0 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sat, 3 Feb 2018 00:55:26 +0800 Subject: Added the GL 3.2+ port. Fixed poor performance of the truetype renderer. (Partially) Fixed texture locking. Minor addition and fixes to the math library. --- smelt/sdl/CxImage/ximajpg.cpp | 538 ------------------------------------------ 1 file changed, 538 deletions(-) delete mode 100644 smelt/sdl/CxImage/ximajpg.cpp (limited to 'smelt/sdl/CxImage/ximajpg.cpp') diff --git a/smelt/sdl/CxImage/ximajpg.cpp b/smelt/sdl/CxImage/ximajpg.cpp deleted file mode 100644 index b66bf97..0000000 --- a/smelt/sdl/CxImage/ximajpg.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/* - * File: ximajpg.cpp - * Purpose: Platform Independent JPEG Image Class Loader and Writer - * 07/Aug/2001 Davide Pizzolato - www.xdp.it - * CxImage version 7.0.0 31/Dec/2010 - */ - -#include "ximajpg.h" - -#if CXIMAGE_SUPPORT_JPG - -#ifdef _LINUX - #include -#else - #include "../jpeg/jmorecfg.h" -#endif - -#include "ximaiter.h" - -#include - -struct jpg_error_mgr { - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ - char* buffer; /* error message */ -}; -typedef jpg_error_mgr *jpg_error_ptr; - -//////////////////////////////////////////////////////////////////////////////// -// Here's the routine that will replace the standard error_exit method: -//////////////////////////////////////////////////////////////////////////////// -static void -ima_jpeg_error_exit (j_common_ptr cinfo) -{ - /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ - jpg_error_ptr myerr = (jpg_error_ptr) cinfo->err; - /* Create the message */ - myerr->pub.format_message (cinfo, myerr->buffer); - /* Send it to stderr, adding a newline */ - /* Return control to the setjmp point */ - longjmp(myerr->setjmp_buffer, 1); -} -//////////////////////////////////////////////////////////////////////////////// -CxImageJPG::CxImageJPG(): CxImage(CXIMAGE_FORMAT_JPG) -{ -#if CXIMAGEJPG_SUPPORT_EXIF - m_exif = NULL; - memset(&info.ExifInfo, 0, sizeof(EXIFINFO)); -#endif -} -//////////////////////////////////////////////////////////////////////////////// -CxImageJPG::~CxImageJPG() -{ -#if CXIMAGEJPG_SUPPORT_EXIF - if (m_exif) delete m_exif; -#endif -} -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGEJPG_SUPPORT_EXIF -bool CxImageJPG::DecodeExif(CxFile * hFile) -{ - m_exif = new CxExifInfo(&info.ExifInfo); - if (m_exif){ - int32_t pos=hFile->Tell(); - m_exif->DecodeExif(hFile); - hFile->Seek(pos,SEEK_SET); - return m_exif->m_exifinfo->IsExif; - } else { - return false; - } -} -//////////////////////////////////////////////////////////////////////////////// -bool CxImageJPG::GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type) -{ - CxIOFile file; - if (!file.Open(filename, _T("rb"))) return false; - CxExifInfo exif(&info.ExifInfo); - exif.DecodeExif(&file); - if (info.ExifInfo.IsExif && info.ExifInfo.ThumbnailPointer && info.ExifInfo.ThumbnailSize > 0) - { // have a thumbnail - check whether it needs rotating or resizing - // TODO: Write a fast routine to read the jpeg header to get the width and height - CxImage image(info.ExifInfo.ThumbnailPointer, info.ExifInfo.ThumbnailSize, CXIMAGE_FORMAT_JPG); - if (image.IsValid()) - { - if (image.GetWidth() > 256 || image.GetHeight() > 256) - { // resize the image -// float amount = 256.0f / max(image.GetWidth(), image.GetHeight()); -// image.Resample((int32_t)(image.GetWidth() * amount), (int32_t)(image.GetHeight() * amount), 0); - } - if (info.ExifInfo.Orientation != 1) - image.RotateExif(info.ExifInfo.Orientation); - return image.Save(outname, CXIMAGE_FORMAT_JPG); - } - // nice and fast, but we can't resize :( - /* - FILE *hFileWrite; - if ((hFileWrite=fopen(outname, "wb")) != NULL) - { - fwrite(m_exifinfo.ThumbnailPointer, m_exifinfo.ThumbnailSize, 1, hFileWrite); - fclose(hFileWrite); - return true; - }*/ - } - return false; -} -#endif //CXIMAGEJPG_SUPPORT_EXIF -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGE_SUPPORT_DECODE -//////////////////////////////////////////////////////////////////////////////// -bool CxImageJPG::Decode(CxFile * hFile) -{ - - bool is_exif = false; -#if CXIMAGEJPG_SUPPORT_EXIF - is_exif = DecodeExif(hFile); -#endif - - CImageIterator iter(this); - /* This struct contains the JPEG decompression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - */ - struct jpeg_decompress_struct cinfo; - /* We use our private extension JPEG error handler. */ - struct jpg_error_mgr jerr; - jerr.buffer=info.szLastError; - /* More stuff */ - JSAMPARRAY buffer; /* Output row buffer */ - int32_t row_stride; /* physical row width in output buffer */ - - /* In this example we want to open the input file before doing anything else, - * so that the setjmp() error recovery below can assume the file is open. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to read binary files. - */ - - /* Step 1: allocate and initialize JPEG decompression object */ - /* We set up the normal JPEG error routines, then override error_exit. */ - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = ima_jpeg_error_exit; - - CxFileJpg src(hFile); - - /* Establish the setjmp return context for my_error_exit to use. */ - if (setjmp(jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. - * We need to clean up the JPEG object, close the input file, and return. - */ - jpeg_destroy_decompress(&cinfo); - return 0; - } - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress(&cinfo); - - /* Step 2: specify data source (eg, a file) */ - //jpeg_stdio_src(&cinfo, infile); - cinfo.src = &src; - - /* Step 3: read file parameters with jpeg_read_header() */ - (void) jpeg_read_header(&cinfo, TRUE); - - /* Step 4 handle decoder options*/ - uint32_t dwCodecOptions = GetCodecOption(CXIMAGE_FORMAT_JPG); //[nm_114] - if ((dwCodecOptions & DECODE_GRAYSCALE) != 0) - cinfo.out_color_space = JCS_GRAYSCALE; - if ((dwCodecOptions & DECODE_QUANTIZE) != 0) { - cinfo.quantize_colors = TRUE; - cinfo.desired_number_of_colors = GetJpegQuality(); - } - if ((dwCodecOptions & DECODE_DITHER) != 0) - cinfo.dither_mode = m_nDither; - if ((dwCodecOptions & DECODE_ONEPASS) != 0) - cinfo.two_pass_quantize = FALSE; - if ((dwCodecOptions & DECODE_NOSMOOTH) != 0) - cinfo.do_fancy_upsampling = FALSE; - -//: Load true color images as RGB (no quantize) -/* Step 4: set parameters for decompression */ -/* if (cinfo.jpeg_color_space!=JCS_GRAYSCALE) { - * cinfo.quantize_colors = TRUE; - * cinfo.desired_number_of_colors = 128; - *} - */ // - - cinfo.scale_num = 1; - // Set the scale - cinfo.scale_denom = GetJpegScale(); - - // Borrowed the idea from GIF implementation - if (info.nEscape == -1) { - // Return output dimensions only - jpeg_calc_output_dimensions(&cinfo); - head.biWidth = cinfo.output_width; - head.biHeight = cinfo.output_height; - info.dwType = CXIMAGE_FORMAT_JPG; - jpeg_destroy_decompress(&cinfo); - return true; - } - - /* Step 5: Start decompressor */ - jpeg_start_decompress(&cinfo); - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available, as well as the output colormap - * if we asked for color quantization. - */ - //Create the image using output dimensions - //Create(cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG); - Create(cinfo.output_width, cinfo.output_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG); - - if (!pDib) longjmp(jerr.setjmp_buffer, 1); // check if the image has been created - - if (is_exif){ -#if CXIMAGEJPG_SUPPORT_EXIF - if ((info.ExifInfo.Xresolution != 0.0) && (info.ExifInfo.ResolutionUnit != 0)) - SetXDPI((int32_t)(info.ExifInfo.Xresolution/info.ExifInfo.ResolutionUnit)); - if ((info.ExifInfo.Yresolution != 0.0) && (info.ExifInfo.ResolutionUnit != 0)) - SetYDPI((int32_t)(info.ExifInfo.Yresolution/info.ExifInfo.ResolutionUnit)); -#endif - } else { - switch (cinfo.density_unit) { - case 0: // [andy] fix for aspect ratio... - if((cinfo.Y_density > 0) && (cinfo.X_density > 0)){ - SetYDPI((int32_t)(GetXDPI()*(float(cinfo.Y_density)/float(cinfo.X_density)))); - } - break; - case 2: // [andy] fix: cinfo.X/Y_density is pixels per centimeter - SetXDPI((int32_t)floor(cinfo.X_density * 2.54 + 0.5)); - SetYDPI((int32_t)floor(cinfo.Y_density * 2.54 + 0.5)); - break; - default: - SetXDPI(cinfo.X_density); - SetYDPI(cinfo.Y_density); - } - } - - if (cinfo.out_color_space==JCS_GRAYSCALE){ - SetGrayPalette(); - head.biClrUsed =256; - } else { - if (cinfo.quantize_colors){ - SetPalette(cinfo.actual_number_of_colors, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]); - head.biClrUsed=cinfo.actual_number_of_colors; - } else { - head.biClrUsed=0; - } - } - - /* JSAMPLEs per row in output buffer */ - row_stride = cinfo.output_width * cinfo.output_components; - - /* Make a one-row-high sample array that will go away when done with image */ - buffer = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - /* Step 6: while (scan lines remain to be read) */ - /* jpeg_read_scanlines(...); */ - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ - iter.Upset(); - while (cinfo.output_scanline < cinfo.output_height) { - - if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // - cancel decoding - - (void) jpeg_read_scanlines(&cinfo, buffer, 1); - // info.nProgress = (int32_t)(100*cinfo.output_scanline/cinfo.output_height); - // Step 6a: CMYK->RGB */ - if ((cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE)){ - uint8_t k,*dst,*src; - dst=iter.GetRow(); - src=buffer[0]; - for(int32_t x3=0,x4=0; x3<(int32_t)info.dwEffWidth && x4 Step 7A: Swap red and blue components - // not necessary if swapped red and blue definition in jmorecfg.h;ln322 - if ((cinfo.num_components==3)&&(cinfo.quantize_colors==FALSE)){ - uint8_t* r0=GetBits(); - for(int32_t y=0;y - cancel decoding - RGBtoBGR(r0,3*head.biWidth); - r0+=info.dwEffWidth; - } - } - - /* Step 8: Release JPEG decompression object */ - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_decompress(&cinfo); - - /* At this point you may want to check to see whether any corrupt-data - * warnings occurred (test whether jerr.pub.num_warnings is nonzero). - */ - - /* And we're done! */ - return true; -} -//////////////////////////////////////////////////////////////////////////////// -#endif //CXIMAGE_SUPPORT_DECODE -//////////////////////////////////////////////////////////////////////////////// -#if CXIMAGE_SUPPORT_ENCODE -//////////////////////////////////////////////////////////////////////////////// -bool CxImageJPG::Encode(CxFile * hFile) -{ - if (EncodeSafeCheck(hFile)) return false; - - if (head.biClrUsed!=0 && !IsGrayScale()){ - strcpy(info.szLastError,"JPEG can save only RGB or GreyScale images"); - return false; - } - - // necessary for EXIF, and for roll backs - int32_t pos=hFile->Tell(); - - /* This struct contains the JPEG compression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - * It is possible to have several such structures, representing multiple - * compression/decompression processes, in existence at once. We refer - * to any one struct (and its associated working data) as a "JPEG object". - */ - struct jpeg_compress_struct cinfo; - /* This struct represents a JPEG error handler. It is declared separately - * because applications often want to supply a specialized error handler - * (see the second half of this file for an example). But here we just - * take the easy way out and use the standard error handler, which will - * print a message on stderr and call exit() if compression fails. - * Note that this struct must live as int32_t as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - //struct jpeg_error_mgr jerr; - /* We use our private extension JPEG error handler. */ - struct jpg_error_mgr jerr; - jerr.buffer=info.szLastError; - /* More stuff */ - int32_t row_stride; /* physical row width in image buffer */ - JSAMPARRAY buffer; /* Output row buffer */ - - /* Step 1: allocate and initialize JPEG compression object */ - /* We have to set up the error handler first, in case the initialization - * step fails. (Unlikely, but it could happen if you are out of memory.) - * This routine fills in the contents of struct jerr, and returns jerr's - * address which we place into the link field in cinfo. - */ - //cinfo.err = jpeg_std_error(&jerr); - /* We set up the normal JPEG error routines, then override error_exit. */ - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = ima_jpeg_error_exit; - - /* Establish the setjmp return context for my_error_exit to use. */ - if (setjmp(jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. - * We need to clean up the JPEG object, close the input file, and return. - */ - strcpy(info.szLastError, jerr.buffer); // - jpeg_destroy_compress(&cinfo); - return 0; - } - - /* Now we can initialize the JPEG compression object. */ - jpeg_create_compress(&cinfo); - /* Step 2: specify data destination (eg, a file) */ - /* Note: steps 2 and 3 can be done in either order. */ - /* Here we use the library-supplied code to send compressed data to a - * stdio stream. You can also write your own code to do something else. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to write binary files. - */ - - //jpeg_stdio_dest(&cinfo, outfile); - CxFileJpg dest(hFile); - cinfo.dest = &dest; - - /* Step 3: set parameters for compression */ - /* First we supply a description of the input image. - * Four fields of the cinfo struct must be filled in: - */ - cinfo.image_width = GetWidth(); // image width and height, in pixels - cinfo.image_height = GetHeight(); - - if (IsGrayScale()){ - cinfo.input_components = 1; // # of color components per pixel - cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */ - } else { - cinfo.input_components = 3; // # of color components per pixel - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ - } - - /* Now use the library's routine to set default compression parameters. - * (You must set at least cinfo.in_color_space before calling this, - * since the defaults depend on the source color space.) - */ - jpeg_set_defaults(&cinfo); - /* Now you can set any non-default parameters you wish to. - * Here we just illustrate the use of quality (quantization table) scaling: - */ - - uint32_t dwCodecOptions = GetCodecOption(CXIMAGE_FORMAT_JPG); //[nm_114] -//#ifdef C_ARITH_CODING_SUPPORTED - if ((dwCodecOptions & ENCODE_ARITHMETIC) != 0) - cinfo.arith_code = TRUE; -//#endif - -//#ifdef ENTROPY_OPT_SUPPORTED - if ((dwCodecOptions & ENCODE_OPTIMIZE) != 0) - cinfo.optimize_coding = TRUE; -//#endif - - if ((dwCodecOptions & ENCODE_GRAYSCALE) != 0) - jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); - - if ((dwCodecOptions & ENCODE_SMOOTHING) != 0) - cinfo.smoothing_factor = m_nSmoothing; - - jpeg_set_quality(&cinfo, GetJpegQuality(), (dwCodecOptions & ENCODE_BASELINE) != 0); - -//#ifdef C_PROGRESSIVE_SUPPORTED - if ((dwCodecOptions & ENCODE_PROGRESSIVE) != 0) - jpeg_simple_progression(&cinfo); -//#endif - -#ifdef C_LOSSLESS_SUPPORTED - if ((dwCodecOptions & ENCODE_LOSSLESS) != 0) - jpeg_simple_lossless(&cinfo, m_nPredictor, m_nPointTransform); -#endif - - //SetCodecOption(ENCODE_SUBSAMPLE_444 | GetCodecOption(CXIMAGE_FORMAT_JPG),CXIMAGE_FORMAT_JPG); - - // 2x2, 1x1, 1x1 (4:1:1) : High (default sub sampling) - cinfo.comp_info[0].h_samp_factor = 2; - cinfo.comp_info[0].v_samp_factor = 2; - cinfo.comp_info[1].h_samp_factor = 1; - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; - cinfo.comp_info[2].v_samp_factor = 1; - - if ((dwCodecOptions & ENCODE_SUBSAMPLE_422) != 0){ - // 2x1, 1x1, 1x1 (4:2:2) : Medium - cinfo.comp_info[0].h_samp_factor = 2; - cinfo.comp_info[0].v_samp_factor = 1; - cinfo.comp_info[1].h_samp_factor = 1; - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; - cinfo.comp_info[2].v_samp_factor = 1; - } - - if ((dwCodecOptions & ENCODE_SUBSAMPLE_444) != 0){ - // 1x1 1x1 1x1 (4:4:4) : None - cinfo.comp_info[0].h_samp_factor = 1; - cinfo.comp_info[0].v_samp_factor = 1; - cinfo.comp_info[1].h_samp_factor = 1; - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; - cinfo.comp_info[2].v_samp_factor = 1; - } - - cinfo.density_unit=1; - cinfo.X_density=(uint16_t)GetXDPI(); - cinfo.Y_density=(uint16_t)GetYDPI(); - - /* Step 4: Start compressor */ - /* TRUE ensures that we will write a complete interchange-JPEG file. - * Pass TRUE unless you are very sure of what you're doing. - */ - jpeg_start_compress(&cinfo, TRUE); - - /* Step 5: while (scan lines remain to be written) */ - /* jpeg_write_scanlines(...); */ - /* Here we use the library's state variable cinfo.next_scanline as the - * loop counter, so that we don't have to keep track ourselves. - * To keep things simple, we pass one scanline per call; you can pass - * more if you wish, though. - */ - row_stride = info.dwEffWidth; /* JSAMPLEs per row in image_buffer */ - - // "8+row_stride" fix heap deallocation problem during debug??? - buffer = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, 8+row_stride, 1); - - CImageIterator iter(this); - - iter.Upset(); - while (cinfo.next_scanline < cinfo.image_height) { - // info.nProgress = (int32_t)(100*cinfo.next_scanline/cinfo.image_height); - iter.GetRow(buffer[0], row_stride); - // not necessary if swapped red and blue definition in jmorecfg.h;ln322 - if (head.biClrUsed==0){ // swap R & B for RGB images - RGBtoBGR(buffer[0], row_stride); // Lance : 1998/09/01 : Bug ID: EXP-2.1.1-9 - } - iter.PrevRow(); - (void) jpeg_write_scanlines(&cinfo, buffer, 1); - } - - /* Step 6: Finish compression */ - jpeg_finish_compress(&cinfo); - - /* Step 7: release JPEG compression object */ - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_compress(&cinfo); - - -#if CXIMAGEJPG_SUPPORT_EXIF - if (m_exif && m_exif->m_exifinfo->IsExif){ - // discard useless sections (if any) read from original image - m_exif->DiscardAllButExif(); - // read new created image, to split the sections - hFile->Seek(pos,SEEK_SET); - m_exif->DecodeExif(hFile,EXIF_READ_IMAGE); - // save back the image, adding EXIF section - hFile->Seek(pos,SEEK_SET); - m_exif->EncodeExif(hFile); - } -#endif - - - /* And we're done! */ - return true; -} -//////////////////////////////////////////////////////////////////////////////// -#endif // CXIMAGE_SUPPORT_ENCODE -//////////////////////////////////////////////////////////////////////////////// -#endif // CXIMAGE_SUPPORT_JPG - -- cgit v1.2.3