From 0e382669d0fb6f9d89a1a4e8a74662b85ba7919e Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Tue, 6 Jun 2023 19:59:17 -0700 Subject: [PATCH] ADDED: Support for saving JPEG files in kicad_pcb When users add an image to the board, this change keeps the original file format when saving instead of converting the files into PNG-format, which had the effect of making some board files much larger and slower Fixes https://gitlab.com/kicad/code/kicad/-/issues/14892 --- common/bitmap_base.cpp | 17 ++++++++++++++--- include/bitmap_base.h | 13 ++++++++++++- pcbnew/plugins/kicad/pcb_parser.cpp | 3 ++- pcbnew/plugins/kicad/pcb_plugin.cpp | 10 ++++++++-- pcbnew/plugins/kicad/pcb_plugin.h | 3 ++- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/common/bitmap_base.cpp b/common/bitmap_base.cpp index c45816ef32..c9d86eeae7 100644 --- a/common/bitmap_base.cpp +++ b/common/bitmap_base.cpp @@ -151,6 +151,7 @@ bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename ) return false; } + m_imageType = new_image->GetType(); delete m_image; m_image = new_image; delete m_originalImage; @@ -167,7 +168,12 @@ bool BITMAP_BASE::SaveData( FILE* aFile ) const if( m_image ) { wxMemoryOutputStream stream; - m_image->SaveFile( stream, wxBITMAP_TYPE_PNG ); + + if( m_imageType == wxBITMAP_TYPE_JPEG ) + m_image->SaveFile( stream, wxBITMAP_TYPE_JPEG ); + else + // Save as PNG (default + m_image->SaveFile( stream, wxBITMAP_TYPE_PNG ); // Write binary data in hexadecimal form (ASCII) wxStreamBuffer* buffer = stream.GetOutputStreamBuffer(); @@ -197,7 +203,12 @@ void BITMAP_BASE::SaveData( wxArrayString& aPngStrings ) const if( m_image ) { wxMemoryOutputStream stream; - m_image->SaveFile( stream, wxBITMAP_TYPE_PNG ); + + if( m_imageType == wxBITMAP_TYPE_JPEG ) + m_image->SaveFile( stream, wxBITMAP_TYPE_JPEG ); + else + // Save as PNG (default + m_image->SaveFile( stream, wxBITMAP_TYPE_PNG ); // Write binary data in hexadecimal form (ASCII) wxStreamBuffer* buffer = stream.GetOutputStreamBuffer(); @@ -244,7 +255,7 @@ bool BITMAP_BASE::LoadData( LINE_READER& aLine, wxString& aErrorMsg ) // We expect here m_image and m_bitmap are void m_image = new wxImage(); wxMemoryInputStream istream( stream ); - m_image->LoadFile( istream, wxBITMAP_TYPE_PNG ); + m_image->LoadFile( istream, wxBITMAP_TYPE_ANY ); m_bitmap = new wxBitmap( *m_image ); m_originalImage = new wxImage( *m_image ); break; diff --git a/include/bitmap_base.h b/include/bitmap_base.h index 96355ead31..a1d6596c52 100644 --- a/include/bitmap_base.h +++ b/include/bitmap_base.h @@ -224,6 +224,16 @@ public: void PlotImage( PLOTTER* aPlotter, const VECTOR2I& aPos, const KIGFX::COLOR4D& aDefaultColor, int aDefaultPensize ) const; + /** + * Return the bitmap type (png, jpeg, etc.) + */ + wxBitmapType GetImageType() const { return m_imageType; } + + /** + * Set the bitmap type (png, jpeg, etc.) + */ + void SetImageType( wxBitmapType aType ) { m_imageType = aType; } + private: /* * Rebuild the internal bitmap used to draw/plot image. @@ -238,7 +248,8 @@ private: double m_scale; // The scaling factor of the bitmap // With m_pixelSizeIu, controls the actual draw size - wxImage* m_image; // the raw image data (png format) + wxImage* m_image; // the raw image data + wxBitmapType m_imageType; // the image type (png, jpeg, etc.) wxImage* m_originalImage; // Raw image data, not transformed by rotate/mirror wxBitmap* m_bitmap; // the bitmap used to draw/plot image double m_pixelSizeIu; // The scaling factor of the bitmap diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp index 1eb971177d..55643ff0d0 100644 --- a/pcbnew/plugins/kicad/pcb_parser.cpp +++ b/pcbnew/plugins/kicad/pcb_parser.cpp @@ -2984,8 +2984,9 @@ PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent ) wxMemoryOutputStream stream( buffer.GetData(), buffer.GetBufSize() ); wxImage* image = new wxImage(); wxMemoryInputStream istream( stream ); - image->LoadFile( istream, wxBITMAP_TYPE_PNG ); + image->LoadFile( istream ); bitmap->SetImage( image ); + bitmap->MutableImage()->SetImageType( image->GetType() ); break; } diff --git a/pcbnew/plugins/kicad/pcb_plugin.cpp b/pcbnew/plugins/kicad/pcb_plugin.cpp index 5d8337a049..a56d4bc103 100644 --- a/pcbnew/plugins/kicad/pcb_plugin.cpp +++ b/pcbnew/plugins/kicad/pcb_plugin.cpp @@ -1041,15 +1041,21 @@ void PCB_PLUGIN::format( const PCB_BITMAP* aBitmap, int aNestLevel ) const m_out->Print( aNestLevel + 1, "(data" ); wxMemoryOutputStream stream; + wxBitmapType type = wxBITMAP_TYPE_PNG; - image->SaveFile( stream, wxBITMAP_TYPE_PNG ); + // Save the image in the same format as the original file + // if it was a JPEG. Otherwise, save it as a PNG. + if( aBitmap->GetImage()->GetImageType() == wxBITMAP_TYPE_JPEG ) + type = wxBITMAP_TYPE_JPEG; + + image->SaveFile( stream, type ); // Write binary data in hexadecimal form (ASCII) wxStreamBuffer* buffer = stream.GetOutputStreamBuffer(); wxString out = wxBase64Encode( buffer->GetBufferStart(), buffer->GetBufferSize() ); // Apparently the MIME standard character width for base64 encoding is 76 (unconfirmed) - // so use it in a vein attempt to be standard like. + // so use it in a vain attempt to be standard like. #define MIME_BASE64_LENGTH 76 size_t first = 0; diff --git a/pcbnew/plugins/kicad/pcb_plugin.h b/pcbnew/plugins/kicad/pcb_plugin.h index 946409c954..3e2ef3a358 100644 --- a/pcbnew/plugins/kicad/pcb_plugin.h +++ b/pcbnew/plugins/kicad/pcb_plugin.h @@ -138,7 +138,8 @@ class PCB_PLUGIN; // forward decl //#define SEXPR_BOARD_FILE_VERSION 20230517 // Teardrop parameters for pads and vias //#define SEXPR_BOARD_FILE_VERSION 20230620 // PCB Fields //#define SEXPR_BOARD_FILE_VERSION 20230730 // Connectivity for graphic shapes -#define SEXPR_BOARD_FILE_VERSION 20230825 // Textbox explicit border flag +//#define SEXPR_BOARD_FILE_VERSION 20230825 // Textbox explicit border flag +#define SEXPR_BOARD_FILE_VERSION 20230606 // Multiple image type support in files #define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag #define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting