1
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // MIT License
4
+ //
5
+ // Copyright(c) 2017 René Slijkhuis
6
+ //
7
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ // of this software and associated documentation files (the "Software"), to deal
9
+ // in the Software without restriction, including without limitation the rights
10
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ // copies of the Software, and to permit persons to whom the Software is
12
+ // furnished to do so, subject to the following conditions:
13
+ //
14
+ // The above copyright notice and this permission notice shall be included in all
15
+ // copies or substantial portions of the Software.
16
+ //
17
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ // SOFTWARE.
24
+ //
25
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26
+
27
+ #include " stdafx.h"
28
+
29
+ #include < vector>
30
+ #include < atlbase.h>
31
+ #include < initguid.h>
32
+ #include < Wincodec.h>
33
+
34
+ using namespace std ;
35
+
36
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
37
+ //
38
+ // Include header: Wincodec.h
39
+ // Add to linker input: Windowscodecs.lib
40
+ //
41
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
42
+
43
+ // GUID of the Lisa image format (this should be known by applications that want to write this format).
44
+ // {91DFBD70-3D2C-440F-B297-1E2097D4A833}
45
+ DEFINE_GUID (GUID_LisaContainerFormat, 0x91dfbd70 , 0x3d2c , 0x440f , 0xb2 , 0x97 , 0x1e , 0x20 , 0x97 , 0xd4 , 0xa8 , 0x33 );
46
+
47
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
48
+
49
+ void SaveAsLisa ( const wstring& filename )
50
+ {
51
+ CoInitialize ( nullptr );
52
+ {
53
+ CComPtr<IWICImagingFactory> pFactory;
54
+ CComPtr<IWICBitmapDecoder> pDecoder;
55
+ CComPtr<IWICBitmapEncoder> pEncoder;
56
+ CComPtr<IWICBitmapFrameDecode> pFrameDecode;
57
+ CComPtr<IWICBitmapFrameEncode> pFrameEncode;
58
+ CComPtr<IWICFormatConverter> pFormatConverter;
59
+ CComPtr<IWICStream> pFileStream;
60
+ CComPtr<IPropertyBag2> pPropertyBag;
61
+
62
+ CoCreateInstance ( CLSID_WICImagingFactory, NULL , CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pFactory );
63
+
64
+ // Read the specified file by using an installed WIC codec.
65
+
66
+ pFactory->CreateDecoderFromFilename ( filename.c_str ( ), NULL , GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder );
67
+ // Check the return value to see if:
68
+ // - The specified file exists and can be read.
69
+ // - A decoder is found for this file format.
70
+
71
+ UINT frameCount = 0 ;
72
+ pDecoder->GetFrameCount ( &frameCount );
73
+
74
+ pDecoder->GetFrame ( 0 , &pFrameDecode );
75
+
76
+ UINT width = 0 ;
77
+ UINT height = 0 ;
78
+ pFrameDecode->GetSize ( &width, &height );
79
+
80
+ WICPixelFormatGUID pixelFormatSource;
81
+ pFrameDecode->GetPixelFormat ( &pixelFormatSource );
82
+
83
+ WICPixelFormatGUID pixelFormatDestination = GUID_WICPixelFormat24bppRGB;
84
+
85
+ // The frame can use many different pixel formats.
86
+ // You can copy the raw pixel values by calling "pFrame->CopyPixels( )".
87
+ // This method needs a buffer that can hold all bytes.
88
+ // The total number of bytes is: width x height x bytes per pixel
89
+
90
+ // The disadvantage of this solution is that you have to deal with all possible pixel formats.
91
+
92
+ // You can make your life easy by converting the frame to a pixel format of
93
+ // your choice. The code below shows how to convert the pixel format to 24-bit RGB.
94
+
95
+ pFactory->CreateFormatConverter ( &pFormatConverter );
96
+
97
+ pFormatConverter->Initialize ( pFrameDecode, // Input bitmap to convert
98
+ pixelFormatDestination, // Destination pixel format
99
+ WICBitmapDitherTypeNone, // Specified dither pattern
100
+ nullptr , // Specify a particular palette
101
+ 0 .f , // Alpha threshold
102
+ WICBitmapPaletteTypeCustom ); // Palette translation type
103
+
104
+ UINT bytesPerPixel = 3 ; // Because we have converted the frame to 24-bit RGB
105
+ UINT stride = width * bytesPerPixel;
106
+ UINT size = width * height * bytesPerPixel; // The size of the required memory buffer for
107
+ // holding all the bytes of the frame.
108
+
109
+ vector<BYTE> bytes ( size ); // The buffer to hold all the bytes of the frame.
110
+ pFormatConverter->CopyPixels ( NULL , stride, size, bytes.data ( ) );
111
+
112
+ // Save the image in the Lisa format.
113
+ // The Lisa WIC codec should be installed (see the link below).
114
+ // https://github.com/ReneSlijkhuis/example-wic-codec
115
+
116
+ pFactory->CreateEncoder ( GUID_LisaContainerFormat, NULL , &pEncoder );
117
+ // Check the return value to see if an encoder is found for the specified file format.
118
+
119
+ pFactory->CreateStream ( &pFileStream );
120
+
121
+ wstring output = filename + L" .lisa" ;
122
+ pFileStream->InitializeFromFilename ( output.c_str ( ), GENERIC_WRITE );
123
+
124
+ pEncoder->Initialize ( pFileStream, WICBitmapEncoderNoCache );
125
+
126
+ pEncoder->CreateNewFrame ( &pFrameEncode, &pPropertyBag );
127
+
128
+ pFrameEncode->SetPixelFormat ( &pixelFormatDestination );
129
+
130
+ pFrameEncode->SetSize ( width, height );
131
+
132
+ pFrameEncode->WritePixels ( height, stride, size, bytes.data ( ) );
133
+
134
+ pFrameEncode->Commit ( );
135
+ pEncoder->Commit ( );
136
+
137
+ // Note: the WIC COM pointers should be released before 'CoUninitialize( )' is called.
138
+ }
139
+ CoUninitialize ( );
140
+ }
141
+
142
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
143
+
144
+ int main ( )
145
+ {
146
+ SaveAsLisa ( L" <filename>" );
147
+
148
+ return 0 ;
149
+ }
150
+
151
+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0 commit comments