1 //*@@@+++@@@@******************************************************************
2 //
3 // Copyright � Microsoft Corp.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 //
9 // � Redistributions of source code must retain the above copyright notice,
10 //   this list of conditions and the following disclaimer.
11 // � Redistributions in binary form must reproduce the above copyright notice,
12 //   this list of conditions and the following disclaimer in the documentation
13 //   and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 // POSSIBILITY OF SUCH DAMAGE.
26 //
27 //*@@@---@@@@******************************************************************
28 
29 #ifndef WMI_WINDOWSMEDIAPHOTO_H
30 #define WMI_WINDOWSMEDIAPHOTO_H
31 
32 //================================================================
33 #include <assert.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #if defined(__cplusplus) && !defined(EXTERN_C)
39 #define EXTERN_C extern "C"
40 #elif !defined(EXTERN_C)// __cplusplus
41 #define EXTERN_C extern
42 #endif // __cplusplus
43 
44 /********************************************************************************
45   Type definitions
46 ********************************************************************************/
47 typedef int Bool;
48 typedef char Char;
49 typedef double Double;
50 typedef int Int;
51 typedef signed char I8;
52 typedef short I16; // 16 bit int
53 typedef int I32;
54 typedef long Long;
55 typedef unsigned char  PixelC;
56 typedef int PixelI;
57 typedef unsigned int UInt;
58 typedef unsigned long ULong;
59 typedef unsigned char U8; // 8 bit uint
60 typedef unsigned short U16;
61 typedef unsigned int U32; // 32 bit uint
62 typedef void Void;
63 
64 typedef void* CTXSTRCODEC;
65 
66 
67 #define REENTRANT_MODE 1
68 /*
69     DESCRIPTION OF COMPILER FLAG REENTRANT_MODE:
70 
71     //#define REENTRANT_MODE 1
72 
73     This compiler flag is related to the capability of banded decode
74     (decoding only one MB row of the source JPEG XR image at a time).
75 
76     With REENTRANT_MODE defined, the decoder decodes one MB row on each call to
77     ImageStrDecDecode().
78 
79     The decoder acts as if it can only write to the single MBRow whose pointer was passed to it.
80     This acts as a proof of concept that the API would work if you passed it a small buffer
81     on each call to ImageStrDecDecode().
82 
83     The REENTRANT_MODE flag only works when the output image is in Orientations 0, 1
84     (vertically	flipped) or 2 (horizontally flipped).
85 
86     With REENTRANT_MODE defined, the function PKImageDecode_Copy_WMP()
87     decodes only as far as the pRect parameter indicates. The width of the rectangle must be the width
88     of the image, but on each call, this function will decode the image up to the end of the MB Row
89     which contains the i-th pixel row, where i = pRect->Y.
90 
91     A target use of this version would be to have PKImageDecode_Copy_WMP() called in a loop, once for
92     each MB row. On each call, pRect would specify a 1-MB-Row-tall rectangle that is the width of the
93     image. The decoder state is preserved until the Decoder finishes decoding the image.
94 
95     If, at a certain point, a request is made for a rectangle _above_ the last row decoded, then the
96     decoder instance is terminated and re-initiated, and decoding re-starts, going from the beginning
97     of the image to the end of the current rectangle.
98 
99     ***
100 
101     We've chosen to uncomment-out this definition in this header file.  An alternate method would be
102     to allow the user to define this in the PREPROCESSOR DEFINITIONS section of the properties page
103     for each of the following projects: CommonLib, DecodeLib, JXRDecApp and JXRGlueLib.
104 
105 */
106 /*************************************************************************
107     enums
108 *************************************************************************/
109 typedef enum {
110     ICERR_OK = 0, ICERR_ERROR = -1
111 } ERR_CODE;
112 
113 typedef enum BITDEPTH {
114     BD_SHORT, BD_LONG,
115 
116     /* add new BITDEPTH here */ BD_MAX
117 } BITDEPTH;
118 
119 typedef enum BITDEPTH_BITS {
120     // regular ones
121     BD_1, //White is foreground
122     BD_8, BD_16, BD_16S, BD_16F, BD_32, BD_32S, BD_32F,
123 
124     // irregular ones
125     BD_5, BD_10, BD_565,
126 
127     /* add new BITDEPTH_BITS here */ BDB_MAX,
128 
129     BD_1alt = 0xf, //Black is foreground
130 } BITDEPTH_BITS;
131 
132 typedef enum OVERLAP {
133     OL_NONE = 0, OL_ONE, OL_TWO,
134 
135     /* add new OVERLAP here */ OL_MAX
136 } OVERLAP;
137 
138 typedef enum BITSTREAMFORMAT {
139     SPATIAL = 0,     // spatial order
140     FREQUENCY,       // frequency order
141 } BITSTREAMFORMAT;
142 
143 typedef enum COLORFORMAT {
144     Y_ONLY  = 0,
145 	YUV_420 = 1,
146 	YUV_422 = 2,
147 	YUV_444 = 3,
148 	CMYK    = 4,
149 	//CMYKDIRECT = 5,
150 	NCOMPONENT = 6,
151 
152     // these are external-only
153     CF_RGB  = 7,
154 	CF_RGBE = 8,
155 
156     /* add new COLORFORMAT here */ CFT_MAX
157 } COLORFORMAT;
158 
159 // rotation and flip
160 typedef enum ORIENTATION {
161     // CRW: Clock Wise 90% Rotation; FlipH: Flip Horizontally;  FlipV: Flip Vertically
162     // Peform rotation FIRST!
163     //                CRW FlipH FlipV
164     O_NONE = 0,    // 0    0     0
165     O_FLIPV,       // 0    0     1
166     O_FLIPH,       // 0    1     0
167     O_FLIPVH,      // 0    1     1
168     O_RCW,         // 1    0     0
169     O_RCW_FLIPV,   // 1    0     1
170     O_RCW_FLIPH,   // 1    1     0
171     O_RCW_FLIPVH,  // 1    1     1
172     /* add new ORIENTATION here */ O_MAX
173 } ORIENTATION;
174 
175 typedef enum SUBBAND {
176     SB_ALL = 0,             // keep all subbands
177     SB_NO_FLEXBITS,     // skip flex bits
178     SB_NO_HIGHPASS,     // skip highpass
179     SB_DC_ONLY,         // skip lowpass and highpass, DC only
180     SB_ISOLATED,        // not decodable
181     /* add new SUBBAND here */ SB_MAX
182 } SUBBAND;
183 
184 enum { RAW = 0, BMP = 1, PPM = 2, TIF = 3, HDR = 4, IYUV = 5, YUV422 = 6, YUV444 = 7};
185 
186 typedef enum {ERROR_FAIL = -1, SUCCESS_DONE, PRE_READ_HDR, PRE_SETUP, PRE_DECODE, POST_READ_HDR } WMIDecoderStatus;
187 
188 #ifndef FALSE
189 #define FALSE 0
190 #endif // FALSE
191 
192 #ifndef TRUE
193 #define TRUE 1
194 #endif // TRUE
195 
196 #define MAX_CHANNELS 16
197 #define LOG_MAX_TILES 12
198 #define MAX_TILES (1 << LOG_MAX_TILES)
199 
200 
201 //================================================================
202 // Codec-specific constants
203 #define MB_WIDTH_PIXEL 16
204 #define MB_HEIGHT_PIXEL 16
205 
206 #define BLK_WIDTH_PIXEL 4
207 #define BLK_HEIGHT_PIXEL 4
208 
209 #define MB_WIDTH_BLK 4
210 #define MB_HEIGHT_BLK 4
211 
212 // The codec operates most efficiently when the framebuffers for encoder input
213 // and decoder output are: 1) aligned on a particular boundary, and 2) the stride
214 // is also aligned to this boundary (so that each scanline is also aligned).
215 // This boundary is defined below.
216 #define FRAMEBUFFER_ALIGNMENT 128
217 
218 
219 //================================================================
220 #define WMP_errSuccess 0
221 
222 #define WMP_errFail -1
223 #define WMP_errNotYetImplemented -2
224 #define WMP_errAbstractMethod -3
225 
226 #define WMP_errOutOfMemory -101
227 #define WMP_errFileIO -102
228 #define WMP_errBufferOverflow -103
229 #define WMP_errInvalidParameter -104
230 #define WMP_errInvalidArgument -105
231 #define WMP_errUnsupportedFormat -106
232 #define WMP_errIncorrectCodecVersion -107
233 #define WMP_errIndexNotFound -108
234 #define WMP_errOutOfSequence -109
235 #define WMP_errNotInitialized -110
236 #define WMP_errMustBeMultipleOf16LinesUntilLastCall -111
237 #define WMP_errPlanarAlphaBandedEncRequiresTempFile -112
238 #define WMP_errAlphaModeCannotBeTranscoded -113
239 #define WMP_errIncorrectCodecSubVersion -114
240 
241 
242 //================================================================
243 typedef long ERR;
244 
245 #define Failed(err) ((err)<0)
246 
247 #define CRLF "\r\n"
248 
249 #define CT_ASSERT(exp, uniq) typedef char __CT_ASSERT__##uniq[(exp) ? 1 : -1] // Caller must provide a unique tag, or this fails to compile under GCC
250 
251 #if defined(_DEBUG) || defined(DBG)
252 #define Report(err, szExp, szFile, nLine) \
253     fprintf(stderr, "FAILED: %ld=%s" CRLF, (err), (szExp)); \
254     fprintf(stderr, "        %s:%ld" CRLF, (szFile), (nLine));  \
255 
256 #else
257 #define Report(err, szExp, szFile, lLine) err = err
258 #endif
259 
260 #define Call(exp) \
261     if (Failed(err = (exp))) \
262     { \
263         Report(err, #exp, __FILE__, (long)__LINE__); \
264         goto Cleanup; \
265     } \
266     else err = err
267 
268 #define CallIgnoreError(errTmp, exp) \
269     if (Failed(errTmp = (exp))) \
270     { \
271         Report(errTmp, #exp, __FILE__, (long)__LINE__); \
272     } \
273     else errTmp = errTmp
274 
275 
276 #define Test(exp, err) Call((exp) ? WMP_errSuccess : (err))
277 #define FailIf(exp, err) Call((exp) ? (err) : WMP_errSuccess)
278 
279 //================================================================
280 // WMPStream interface
281 //================================================================
282 struct WMPStream
283 {
284     union
285     {
286         struct tagFile
287         {
288             FILE* pFile;
289         } file;
290 
291         struct tagBuf
292         {
293             U8* pbBuf;
294             size_t cbBuf;
295             size_t cbCur;
296             size_t cbBufCount;
297         } buf;
298 
299         void* pvObj;
300     } state;
301 
302     Bool fMem;
303 
304     ERR (*Close)(struct WMPStream** pme);
305 
306     Bool (*EOS)(struct WMPStream* me);
307 
308     ERR (*Read)(struct WMPStream* me, void* pv, size_t cb);
309     ERR (*Write)(struct WMPStream* me, const void* pv, size_t cb);
310     //ERR (*GetLine)(struct WMPStream* me, void* pv, size_t cb);
311 
312     ERR (*SetPos)(struct WMPStream* me, size_t offPos);
313     ERR (*GetPos)(struct WMPStream* me, size_t* poffPos);
314 };
315 
316 EXTERN_C ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode);
317 EXTERN_C ERR CloseWS_File(struct WMPStream** ppWS);
318 
319 EXTERN_C ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb);
320 EXTERN_C ERR CloseWS_Memory(struct WMPStream** ppWS);
321 
322 
323 //================================================================
324 // Enc/Dec data structure
325 //================================================================
326 typedef struct tagCWMImageInfo {
327     size_t cWidth;
328     size_t cHeight;
329     COLORFORMAT cfColorFormat;
330     BITDEPTH_BITS bdBitDepth;
331     size_t cBitsPerUnit;
332     size_t cLeadingPadding; // number of leading padding
333     Bool bRGB; // true: RGB;  false: BGR
334     U8 cChromaCenteringX; // Relative location of Chroma w.r.t Luma
335     U8 cChromaCenteringY; // Relative location of Chroma w.r.t Luma
336 
337     // Region of interest decoding
338     size_t cROILeftX;
339     size_t cROIWidth;
340     size_t cROITopY;
341     size_t cROIHeight;
342 
343     // thumbnail decode
344     Bool   bSkipFlexbits;
345     size_t cThumbnailWidth;
346     size_t cThumbnailHeight;
347 
348     // image orientation
349     ORIENTATION oOrientation;
350 
351     // post processing
352     U8 cPostProcStrength; // 0(none) 1(light) 2(medium) 3(strong) 4(very strong)
353 
354     // user buffer is always padded to whole MB
355     Bool fPaddedUserBuffer;
356 } CWMImageInfo;
357 
358 typedef struct tagCWMIStrCodecParam {
359     Bool bVerbose;
360 
361     // for macroblock quantization (DQUANT)
362     U8 uiDefaultQPIndex;
363     U8 uiDefaultQPIndexYLP;
364     U8 uiDefaultQPIndexYHP;
365     U8 uiDefaultQPIndexU;
366     U8 uiDefaultQPIndexULP;
367     U8 uiDefaultQPIndexUHP;
368     U8 uiDefaultQPIndexV;
369     U8 uiDefaultQPIndexVLP;
370     U8 uiDefaultQPIndexVHP;
371     U8 uiDefaultQPIndexAlpha;
372 
373     COLORFORMAT cfColorFormat;
374     BITDEPTH bdBitDepth;
375     OVERLAP olOverlap;
376     BITSTREAMFORMAT bfBitstreamFormat;
377     size_t cChannel; // number of color channels including alpha
378     U8 uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha
379     SUBBAND sbSubband;  // which subbands to keep
380     U8  uiTrimFlexBits;
381 
382     struct WMPStream* pWStream;
383     size_t cbStream;
384 
385     // tiling info
386     U32  cNumOfSliceMinus1V;     // # of vertical slices
387     U32 uiTileX[MAX_TILES]; // width in MB of each veritical slice
388     U32  cNumOfSliceMinus1H;     // # of horizontal slices
389     U32 uiTileY[MAX_TILES]; // height in MB of each horizontal slice
390 
391     //32f and 32s conversion parameters
392     U8 nLenMantissaOrShift;
393     I8 nExpBias;
394 
395     Bool bBlackWhite;
396 
397     Bool bUseHardTileBoundaries; //default is soft tile boundaries
398 
399     Bool bProgressiveMode; //default is sequential mode
400 
401     Bool bYUVData; //default is cfColorFormat data
402 
403     Bool bUnscaledArith; //force unscaled arithmetic
404 
405     // Perf measurement
406     Bool fMeasurePerf;
407 } CWMIStrCodecParam;
408 
409 typedef struct tagCWMImageBufferInfo {
410     void* pv;           // pointer to scanline buffer
411     size_t cLine;       // count of scanlines
412     size_t cbStride;    // count of BYTE for stride
413 #ifdef REENTRANT_MODE
414     unsigned int uiFirstMBRow;     // Current First MB Row being decoded
415     unsigned int uiLastMBRow;     // Current Last MB Row being decoded
416     size_t cLinesDecoded;         // Number of lines decoded and returned in low-mem mode
417 #endif // REENTRANT_MODE
418 } CWMImageBufferInfo;
419 
420 
421 
422 
423 /****************************************************************/
424 /* Encode API                                                   */
425 /****************************************************************/
426 EXTERN_C Int ImageStrEncInit(
427     CWMImageInfo* pII,
428     CWMIStrCodecParam *pSCP,
429     CTXSTRCODEC* pctxSC);
430 
431 EXTERN_C Int ImageStrEncEncode(
432     CTXSTRCODEC ctxSC,
433     const CWMImageBufferInfo* pBI);
434 
435 EXTERN_C Int ImageStrEncTerm(
436     CTXSTRCODEC ctxSC);
437 
438 
439 /****************************************************************/
440 /* Decode API                                                   */
441 /****************************************************************/
442 struct CWMImageStrCodec;
443 
444 EXTERN_C Int ImageStrDecGetInfo(
445     CWMImageInfo* pII,
446     CWMIStrCodecParam *pSCP);
447 
448 EXTERN_C Int ImageStrDecInit(
449     CWMImageInfo* pII,
450     CWMIStrCodecParam *pSCP,
451     CTXSTRCODEC* pctxSC);
452 
453 EXTERN_C Int ImageStrDecDecode(
454     CTXSTRCODEC ctxSC,
455     const CWMImageBufferInfo* pBI
456 #ifdef REENTRANT_MODE
457     , size_t *pcDecodedLines
458 #endif
459     );
460 
461 EXTERN_C Int ImageStrDecTerm(
462     CTXSTRCODEC ctxSC);
463 
464 EXTERN_C Int WMPhotoValidate(
465     CWMImageInfo * pII,
466     CWMIStrCodecParam * pSCP);
467 
468 
469 /****************************************************************/
470 /* Transcoding API                                              */
471 /****************************************************************/
472 typedef struct tagCWMTranscodingParam {
473     size_t cLeftX;
474     size_t cWidth;
475     size_t cTopY;
476     size_t cHeight;  // interested region
477 
478     BITSTREAMFORMAT bfBitstreamFormat; // desired bitstream format
479 //    COLORFORMAT cfColorFormat; // desired color format
480     U8 uAlphaMode; // 0:no alpha 1: alpha only else: something + alpha
481     SUBBAND sbSubband;  // which subbands to keep
482     ORIENTATION oOrientation; // flip / right angle rotation
483     Bool bIgnoreOverlap;
484 } CWMTranscodingParam;
485 
486 EXTERN_C Int WMPhotoTranscode(
487     struct WMPStream* pStreamDec,   // input bitstrean
488     struct WMPStream* pStreamEnc,   // output bitstream
489     CWMTranscodingParam* pParam     // transcoding parameters
490 );
491 
492 typedef struct tagCWMDetilingParam {
493     size_t cWidth;
494     size_t cHeight;  // image size
495     size_t cChannel; // # of channels
496     OVERLAP olOverlap; // overlap
497     BITDEPTH_BITS bdBitdepth; // bit depth
498 
499     // tiling info
500     U32  cNumOfSliceMinus1V;     // # of vertical slices
501     U32 uiTileX[MAX_TILES]; // position in MB of each veritical slice
502     U32  cNumOfSliceMinus1H;     // # of horizontal slices
503     U32 uiTileY[MAX_TILES]; // position in MB of each horizontal slice
504 
505     // image info
506     void * pImage;
507     size_t cbStride;
508 } CWMDetilingParam;
509 
510 EXTERN_C Int WMPhotoDetile(
511     CWMDetilingParam * pParam   // detiling parameters
512 );
513 
514 #endif // WMI_WINDOWSMEDIAPHOTO_H
515 
516