Skip to content

Commit

Permalink
Revert "Cleanup and minor fixes"
Browse files Browse the repository at this point in the history
This reverts commit e248d08.
  • Loading branch information
lucianpls committed Jan 21, 2021
1 parent e248d08 commit 9fc5247
Show file tree
Hide file tree
Showing 17 changed files with 1,102 additions and 658 deletions.
2 changes: 1 addition & 1 deletion gdal/frmts/mrf/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
include ../../GDALmake.opt

PLUGIN_PATH = $(prefix)/lib/gdalplugins/$(GDAL_VERSION_MAJOR).$(GDAL_VERSION_MINOR)
FILES = marfa_dataset mrf_band JPEG_band PNG_band JPNG_band Tif_band Packer_RLE mrf_util mrf_overview
FILES = marfa_dataset mrf_band JPEG_band PNG_band JPNG_band Raw_band Tif_band Packer_RLE mrf_util mrf_overview
OBJ = $(addsuffix .o, $(FILES))
LO_O_OBJ = $(addsuffix .lo,$(basename $(O_OBJ)))
DEPENDS = marfa.h
Expand Down
5 changes: 1 addition & 4 deletions gdal/frmts/mrf/JPEG12_band.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2021 Esri
* Copyright 2015 Esri
* 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
Expand All @@ -11,9 +11,6 @@
* 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.
*
* Author: Lucian Plesea
*
*/

#include "marfa.h"
Expand Down
82 changes: 45 additions & 37 deletions gdal/frmts/mrf/JPEG_band.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2014-2021 Esri
* Copyright 2014-2015 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -31,30 +31,29 @@
* 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.
*
* Author: Lucian Plesea
*
*
* JPEG band
* JPEG page compression and decompression functions, file gets compiled twice
* once directly and once through inclusion from JPEG12_band.cpp
* LIBJPEG_12_H is defined if both 8 and 12 bit JPEG will be supported
* JPEG12_ON is defined only for the 12 bit versions
*
* The MRF JPEG codec implements the Zen (Zero ENhanced) JPEG extension
* This extension, when supported by the decompressor, preserves the zero or non-zero state of all pixels
* which allows zero pixels to be used as a non-data mask
* Clients which don't support the Zen extension will read it as a normal JPEG
*
* On page writes, a mask of all fully zero pixels is built
* If the mask has some zero pixels, it is written in a JPEG APP3 "Zen" marker
* If the mask has no zero pixels, a zero length APP3 marker is inserted
*
* On page reads, after the JPEG decompression, if a mask or a zero length APP3 marker is detected,
* the masked pixels with value of zero are set to 1 while the non-masked ones are set to zero
*
*/

/*
* JPEG band
* JPEG page compression and decompression functions, gets compiled twice
* once directly and once through inclusion from JPEG12_band.cpp
* LIBJPEG_12_H is defined if both 8 and 12 bit JPEG will be supported
* JPEG12_ON is defined for the 12 bit versions
*
* The MRF JPEG codec implements the Zen (Zero ENhanced) JPEG extension
* This extension, when supported by the decompressor, preserves the zero or non-zero state of all pixels
* which allows zero pixels to be used as a non-data mask
* Clients which don't support the Zen extension will read it as a normal JPEG
*
* On page writes, a mask of all fully zero pixels is built
* If the mask has some zero pixels, it is written in a JPEG APP3 "Zen" marker
* If the mask has no zero pixels, a zero length APP3 marker is inserted
*
* On page reads, after the JPEG decompression, if a mask or a zero length APP3 marker is detected,
* the masked pixels with value of zero are set to 1 while the non-masked ones are set to zero
*
*/

#include "marfa.h"
#include <setjmp.h>

Expand All @@ -67,6 +66,8 @@ CPL_C_END
#include "BitMask2D.h"
#include "Packer_RLE.h"

CPL_CVSID("$Id$")

NAMESPACE_MRF_START

typedef BitMap2D<> BitMask;
Expand Down Expand Up @@ -141,7 +142,7 @@ static boolean fill_input_buffer_dec(j_decompress_ptr cinfo)
}

/**
*\brief: Skips unknown chunks
*\brief: Do nothing stub function for JPEG library, not called
*/
static void skip_input_data_dec(j_decompress_ptr cinfo, long l) {
struct jpeg_source_mgr *src = cinfo->src;
Expand Down Expand Up @@ -279,7 +280,7 @@ CPLErr JPEG_Codec::CompressJPEG(buf_mgr &dst, buf_mgr &src)
}

// Build a bitmaps of the black pixels
// If there are any black pixels, write a compressed mask in APP3 "Zen" chunk
// If there are any black pixels, write a compressed mask in APP3 "C3Mask" chunk

// Mask is initialized to all pixels valid
BitMask mask(sz.x, sz.y);
Expand Down Expand Up @@ -472,7 +473,7 @@ static boolean MaskProcessor(j_decompress_ptr pcinfo) {
#if defined(JPEG12_ON)
CPLErr JPEG_Codec::DecompressJPEG12(buf_mgr &dst, buf_mgr &isrc)
#else
CPLErr JPEG_Codec::DecompressJPEG(buf_mgr& dst, buf_mgr& isrc)
CPLErr JPEG_Codec::DecompressJPEG(buf_mgr &dst, buf_mgr &isrc)
#endif

{
Expand All @@ -491,12 +492,12 @@ CPLErr JPEG_Codec::DecompressJPEG(buf_mgr& dst, buf_mgr& isrc)

struct jpeg_source_mgr src;

cinfo.err = jpeg_std_error(&sJErr);
cinfo.err = jpeg_std_error( &sJErr );
sJErr.error_exit = errorExit;
sJErr.emit_message = emitMessage;
cinfo.client_data = &sJPEGStruct;
cinfo.client_data = (void *) &(sJPEGStruct);

src.next_input_byte = reinterpret_cast<JOCTET*>(isrc.buffer);
src.next_input_byte = (JOCTET *)isrc.buffer;
src.bytes_in_buffer = isrc.size;
src.term_source = stub_source_dec;
src.init_source = stub_source_dec;
Expand All @@ -518,7 +519,8 @@ CPLErr JPEG_Codec::DecompressJPEG(buf_mgr& dst, buf_mgr& isrc)

/* In some cases, libjpeg needs to allocate a lot of memory */
/* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */
if (jpeg_has_multiple_scans(&(cinfo))) {
if( jpeg_has_multiple_scans(&(cinfo)) )
{
/* In this case libjpeg will need to allocate memory or backing */
/* store for all coefficients */
/* See call to jinit_d_coef_controller() from master_selection() */
Expand Down Expand Up @@ -571,7 +573,8 @@ CPLErr JPEG_Codec::DecompressJPEG(buf_mgr& dst, buf_mgr& isrc)
cinfo.out_color_space = JCS_GRAYSCALE;

const int datasize = ((cinfo.data_precision == 8) ? 1 : 2);
if (cinfo.image_width > static_cast<unsigned>(INT_MAX / (nbands * datasize))) {
if( cinfo.image_width > static_cast<unsigned>(INT_MAX / (nbands * datasize)) )
{
CPLError(CE_Failure, CPLE_AppDefined, "MRF: JPEG decompress buffer overflow");
jpeg_destroy_decompress(&cinfo);
return CE_Failure;
Expand Down Expand Up @@ -607,7 +610,8 @@ CPLErr JPEG_Codec::DecompressJPEG(buf_mgr& dst, buf_mgr& isrc)
rp[1] = rp[0] + linesize;
// if this fails, it calls the error handler
// which will report an error
if (jpeg_read_scanlines(&cinfo, JSAMPARRAY(rp), 2) == 0) {
if( jpeg_read_scanlines(&cinfo, JSAMPARRAY(rp), 2) == 0 )
{
jpeg_destroy_decompress(&cinfo);
return CE_Failure;
}
Expand All @@ -624,7 +628,7 @@ CPLErr JPEG_Codec::DecompressJPEG(buf_mgr& dst, buf_mgr& isrc)
return CE_None;
}

// From here to end it gets compiled only once
// This part gets compiled only once
#if !defined(JPEG12_ON)

// The Zen chunk signature
Expand All @@ -633,15 +637,17 @@ size_t CHUNK_NAME_SIZE = strlen(CHUNK_NAME) + 1;


// Type dependent dispachers
CPLErr JPEG_Band::Decompress(buf_mgr &dst, buf_mgr &src) {
CPLErr JPEG_Band::Decompress(buf_mgr &dst, buf_mgr &src)
{
#if defined(LIBJPEG_12_H)
if (GDT_Byte != img.dt)
return codec.DecompressJPEG12(dst, src);
#endif
return codec.DecompressJPEG(dst, src);
}

CPLErr JPEG_Band::Compress(buf_mgr &dst, buf_mgr &src) {
CPLErr JPEG_Band::Compress(buf_mgr &dst, buf_mgr &src)
{
#if defined(LIBJPEG_12_H)
if (GDT_Byte != img.dt)
return codec.CompressJPEG12(dst, src);
Expand All @@ -668,9 +674,11 @@ JPEG_Band::JPEG_Band( MRFDataset *pDS, const ILImage &image,
return;
}

if( nbands == 3 ) { // Only the 3 band JPEG has storage flavors
if( nbands == 3 )
{ // Only the 3 band JPEG has storage flavors
CPLString const &pm = pDS->GetPhotometricInterpretation();
if (pm == "RGB" || pm == "MULTISPECTRAL") { // Explicit RGB or MS
if (pm == "RGB" || pm == "MULTISPECTRAL")
{ // Explicit RGB or MS
codec.rgb = TRUE;
codec.sameres = TRUE;
}
Expand Down
93 changes: 62 additions & 31 deletions gdal/frmts/mrf/JPNG_band.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/*
* Copyright 2016-2021 Esri
*
* Author: Lucian Plesea
* Copyright 2016 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,10 +19,16 @@
*/

#include "marfa.h"
CPL_CVSID("$Id$")

CPL_C_START
#include <jpeglib.h>

#ifdef INTERNAL_PNG
#include "../png/libpng/png.h"
#else
#include <png.h>
#endif
CPL_C_END

NAMESPACE_MRF_START
Expand All @@ -39,6 +43,11 @@ template<int N> static bool AllAlpha(const buf_mgr &src, const ILImage &img) {
return s >= stop;
}

// Fully opaque
#define opaque AllAlpha<255>
// Fully transparent
#define transparent AllAlpha<0>

// Strip the alpha from an RGBA buffer, safe to use in place
static void RGBA2RGB(const char *start, const char *stop, char *target) {
while (start < stop) {
Expand Down Expand Up @@ -77,19 +86,22 @@ static void L2LA(const char *start, char *stop, const char *source_end) {
}
}

static CPLErr initBuffer(buf_mgr &b) {
static CPLErr initBuffer(buf_mgr &b)
{
b.buffer = (char *)(CPLMalloc(b.size));
if (b.buffer != nullptr)
return CE_None;
CPLError(CE_Failure, CPLE_OutOfMemory, "Allocating temporary JPNG buffer");
return CE_Failure;
}

CPLErr JPNG_Band::Decompress(buf_mgr &dst, buf_mgr &src) {
CPLErr JPNG_Band::Decompress(buf_mgr &dst, buf_mgr &src)
{
CPLErr retval = CE_None;

const static GUInt32 JPEG_SIG = 0xe0ffd8ff; // JPEG 4CC code
const static GUInt32 PNG_SIG = 0x474e5089; // PNG 4CC code

CPLErr retval = CE_None;
ILImage image(img);
GUInt32 signature;
memcpy(&signature, src.buffer, sizeof(GUInt32));
Expand All @@ -111,45 +123,57 @@ CPLErr JPNG_Band::Decompress(buf_mgr &dst, buf_mgr &src) {
L2LA(dst.buffer, dst.buffer + dst.size, temp.buffer + temp.size);
}
}
else if (PNG_SIG == CPL_LSBWORD32(signature)) { // Should be PNG, it reads as 4 bands
else if( PNG_SIG == CPL_LSBWORD32(signature) ) { // Should be PNG
PNG_Codec codec(image);
// PNG codec expands to 4 bands
return codec.DecompressPNG(dst, src);
}
else {
CPLError(CE_Failure, CPLE_NotSupported, "Not a JPEG or PNG tile");
CPLError(CE_Failure, CPLE_NotSupported,
"Not a JPEG or PNG tile");
retval = CE_Failure;
}

return retval;
}

// The PNG internal palette is set on first band write
CPLErr JPNG_Band::Compress(buf_mgr &dst, buf_mgr &src) {
CPLErr JPNG_Band::Compress(buf_mgr &dst, buf_mgr &src)
{
ILImage image(img);

buf_mgr temp = { nullptr, static_cast<size_t>(img.pageSizeBytes) };
CPLErr retval = initBuffer(temp);
if (retval != CE_None)
return retval;

if (AllAlpha<255>(src, image)) { // If all pixels are opaque, compress as JPEG
if (image.pagesize.c == 4)
RGBA2RGB(src.buffer, src.buffer + src.size, temp.buffer);
try {
if (opaque(src, image)) { // If all pixels are opaque, compress as JPEG
if (image.pagesize.c == 4)
RGBA2RGB(src.buffer, src.buffer + src.size, temp.buffer);
else
LA2L(src.buffer, src.buffer + src.size, temp.buffer);

image.pagesize.c -= 1; // RGB or Grayscale only for JPEG
JPEG_Codec codec(image);
codec.rgb = rgb;
codec.optimize = optimize;
codec.sameres = sameres;
retval = codec.CompressJPEG(dst, temp);
}
else if (transparent(src, image)) {
dst.size = 0; // Don't store fully transparent pages
}
else
LA2L(src.buffer, src.buffer + src.size, temp.buffer);

image.pagesize.c -= 1; // RGB or Grayscale only for JPEG
JPEG_Codec codec(image);
codec.rgb = rgb;
codec.optimize = optimize;
codec.sameres = sameres;
retval = codec.CompressJPEG(dst, temp);
{
PNG_Codec codec(image);
codec.deflate_flags = deflate_flags;
retval = codec.CompressPNG(dst, src);
}
}
else if (!AllAlpha<0>(src, image)) {
PNG_Codec codec(image);
codec.deflate_flags = deflate_flags;
retval = codec.CompressPNG(dst, src);
catch (const CPLErr& err) {
retval = err;
}
else dst.size = 0; // Don't store fully transparent pages

CPLFree(temp.buffer);
return retval;
Expand All @@ -167,18 +191,25 @@ JPNG_Band::JPNG_Band( MRFDataset *pDS, const ILImage &image,
sameres(FALSE),
optimize(false)
{ // Check error conditions
if (image.dt != GDT_Byte) {
CPLError(CE_Failure, CPLE_NotSupported, "Data type not supported by MRF JPNG");
if( image.dt != GDT_Byte )
{
CPLError(CE_Failure, CPLE_NotSupported,
"Data type not supported by MRF JPNG");
return;
}
if (image.order != IL_Interleaved || (image.pagesize.c != 4 && image.pagesize.c != 2)) {
CPLError(CE_Failure, CPLE_NotSupported, "MRF JPNG can only handle 2 or 4 interleaved bands");
if( image.order != IL_Interleaved ||
(image.pagesize.c != 4 && image.pagesize.c != 2) )
{
CPLError(CE_Failure, CPLE_NotSupported,
"MRF JPNG can only handle 2 or 4 interleaved bands");
return;
}

if (img.pagesize.c == 4) { // RGBA can have storage flavors
if( img.pagesize.c == 4 )
{ // RGBA can have storage flavors
CPLString const &pm = pDS->GetPhotometricInterpretation();
if (pm == "RGB" || pm == "MULTISPECTRAL") { // Explicit RGB or MS
if (pm == "RGB" || pm == "MULTISPECTRAL")
{ // Explicit RGB or MS
rgb = TRUE;
sameres = TRUE;
}
Expand Down
2 changes: 1 addition & 1 deletion gdal/frmts/mrf/LERCV1/Lerc1Image.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2015 - 2021 Esri
Copyright 2015 - 2020 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Loading

0 comments on commit 9fc5247

Please sign in to comment.