1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     jpeg_MpEncoder.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 26510 $
14  *---------------------------------------------------------------------------*/
15 
16 /*! @file
17     @brief    JpegMpEncoder に関するAPIの宣言
18 
19     :include nn/jpeg.h
20 */
21 
22 #ifndef NN_JPEG_JPEGMPENCODER_H_
23 #define NN_JPEG_JPEGMPENCODER_H_
24 
25 #include <nn/util/util_NonCopyable.h>
26 #include <nn/jpeg/CTR/jpeg_MpTypes.h>
27 #include <string.h>
28 
29 #ifdef __cplusplus
30 
31 namespace nn {
32 namespace jpeg {
33 namespace CTR {
34 
35 namespace detail {
36     struct JpegMpEncoderWorkObj;
37 }
38 
39 /*!
40     @brief JPEGエンコードを行うクラスです。
41 */
42 class JpegMpEncoder : private nn::util::NonCopyable<JpegMpEncoder>
43 {
44 public:
45     /*!
46         @brief      エンコーダオブジェクト用ワークバッファのバイト数を計算します。
47 
48                     バッファの確保と解放はアプリケーションで行ってください。
49 
50         @param[in]  numImages   MP(マルチピクチャ)フォーマットを使用せず、通常のJPEGフォーマットのみを使用する場合は0を指定します。<BR>
51                                 MPフォーマットを使用する場合は、格納する画像数を指定します。<BR>
52                                 MPフォーマットを使用するかどうか、あるいは格納する画像数が未定のままバッファを確保する必要がある場合、
53                                 アプリケーションが想定する最大格納画像数を指定してください。<BR>
54                                 デフォルトは0です。
55 
56         @return     バッファのバイト数を返します。
57                     ただし、格納する画像数(numImages)が大きすぎる(4096以上)場合には、エラーとして0を返します。
58      */
59     static size_t GetWorkBufferSize(u32 numImages = 0);
60 
61     /*!
62         @brief      エンコーダオブジェクトを構築します。
63 
64                     初期化しません。
65      */
JpegMpEncoder()66     JpegMpEncoder() : m_Initialized(false) {}
67 
68     /*!
69         @brief      エンコーダオブジェクトを初期化します。
70 
71                     エンコーダオブジェクト用ワークバッファも初期化します。
72 
73                     初期化を一度行えば、MPフォーマットへ格納する画像数に変更がない限り、終了するまで再初期化不要です。
74                     @ref StartMpEncoderNext を呼ぶ前でなければ、再初期化してもかまいません。
75 
76         @param[out] workBuffer          エンコーダオブジェクト用ワークバッファを指定します。
77                                         4バイトアラインメントが必要です。<BR>
78                                         バッファサイズは @ref GetWorkBufferSize で計算します。<BR>
79                                         ワークバッファはエンコーダオブジェクト毎に必要です。
80 
81         @param[in]  workBufferSize      バッファのバイト数を指定します。
82                                         @ref GetWorkBufferSize の返り値を指定してください。
83 
84         @param[in]  numImages           MPフォーマットへ格納する画像数を指定します。<BR>
85                                         @ref GetWorkBufferSize 呼び出し時と同じかそれ以下の値を指定してください。<BR>
86                                         デフォルトは0です。
87 
88         @return     成功した場合、trueを返します。
89                     失敗した場合、falseを返します。
90                     workBufferのアラインメントと、他の引数を確認してください。
91      */
92     bool Initialize(void* workBuffer, size_t workBufferSize, u32 numImages = 0);
93 
94     /*!
95         @brief      サムネイルの画像サイズおよび出力形式を指定します。
96 
97                     エンコード関数がサムネイルを付加する場合、
98                     サムネイルの画像サイズ(pixel)は、デフォルトでは横幅 @ref DEFAULT_THUMBNAIL_WIDTH (160)、
99                     縦幅 @ref DEFAULT_THUMBNAIL_HEIGHT (120) となり、アスペクト比は4:3です。
100 
101                     サムネイルは指定された画像サイズで生成されるため、元画像のアスペクト比が4:3でない場合、
102                     縮小率が縦方向と横方向で異なる、歪んだサムネイルが生成されます。
103 
104                     本関数でサムネイル画像サイズを指定することにより、元画像とサムネイルのアスペクト比を一致あるいは近づけることができます。
105                     サムネイル画像サイズを大きくしすぎると、APP1セグメント(0xFFFFバイトまで)に収まらず、エンコードが失敗する可能性があります。
106 
107                     指定できる画像サイズは、出力形式(引数 dstPixelSampling)によって変わります。<BR>
108                     @ref PIXEL_SAMPLING_YUV444 を指定した場合は、縦横サイズがそれぞれ8の倍数である必要があります。<BR>
109                     @ref PIXEL_SAMPLING_YUV420 を指定した場合は、縦横サイズがそれぞれ16の倍数である必要があります。<BR>
110                     @ref PIXEL_SAMPLING_YUV422 を指定した場合は、縦サイズが8の倍数、横サイズが16の倍数である必要があります。
111 
112                     デフォルトの画像出力形式は @ref DEFAULT_THUMBNAIL_PIXEL_SAMPLING ( @ref PIXEL_SAMPLING_YUV422 ) です。
113 
114                     本関数は、エンコード関数を呼ぶ前に呼んでください。
115                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
116                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
117                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
118 
119                     引数 width、height、dstPixelSamplingの組み合わせが不正な場合は、
120                     全てデフォルト値で置き換えられます。
121 
122         @param[in]  width               サムネイルの横幅(pixel)を指定します。(65536未満)
123 
124         @param[in]  height              サムネイルの縦幅(pixel)を指定します。(65536未満)
125 
126         @param[in]  dstPixelSampling    画像の出力形式(画素サンプリング)を指定します。<BR>
127                                         デフォルトは @ref DEFAULT_THUMBNAIL_PIXEL_SAMPLING ( @ref PIXEL_SAMPLING_YUV422 ) です。
128 
129         @return     なし。
130      */
131     void SetThumbnailSize(u32 width, u32 height, PixelSampling dstPixelSampling = DEFAULT_THUMBNAIL_PIXEL_SAMPLING)
132     {
133         if (m_Initialized)
134         {
135             m_TemporarySetting.thumbnailWidth    = width;
136             m_TemporarySetting.thumbnailHeight   = height;
137             m_TemporarySetting.thumbnailSampling = dstPixelSampling;
138         }
139     }
140 
141     /*!
142         @brief      入力画像バッファの横幅を指定します。
143 
144                     本関数は、エンコードしたい画像横幅より、その画像バッファ(例えばGPUテクスチャバッファ)
145                     の画像横幅が大きい場合に使います。
146 
147                     入力画像バッファの画像横幅を指定することにより、
148                     エンコード関数が入力画像バッファから左詰めで切り抜き処理を行います。
149                     サムネイルを付加する場合、主画像と同様に切り抜き後の画像から縮小処理を行います。
150 
151                     本関数は、エンコード関数を呼ぶ前に呼んでください。
152                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
153                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
154                     他にも、引数 width に0を指定するか、
155                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
156 
157                     本関数で指定した画像横幅より、エンコード関数で指定したものが大きい場合は、
158                     エンコード関数の指定が優先されます。
159 
160                     引数 width は、エンコード関数で指定する入力ピクセルフォーマットに応じて以下の制限があります。
161                     (エンコード時にそれぞれの倍数へ切り下げられます)<BR>
162                     @ref PIXEL_FORMAT_YUYV8 の場合、2の倍数である必要があります。<BR>
163                     @ref PIXEL_FORMAT_CTR_RGB565_BLOCK8 、@ref PIXEL_FORMAT_CTR_RGB8_BLOCK8 、あるいは @ref PIXEL_FORMAT_CTR_RGBA8_BLOCK8 の場合、8の倍数である必要があります。
164 
165         @param[in]  width               入力画像バッファの横幅(pixel)を指定します。<BR>
166                                         0を指定すると、エンコード関数での指定が優先されます。<BR>
167                                         MAX_ENCODER_INPUT_BUFFER_WIDTH (65536) を超える値の指定は無視されます。
168 
169         @return     なし。
170      */
SetInputBufferWidth(u32 width)171     void SetInputBufferWidth(u32 width)
172     {
173         if (m_Initialized)
174         {
175             if (width <= MAX_ENCODER_INPUT_BUFFER_WIDTH)
176             {
177                 m_TemporarySetting.inputBufferWidth  = width;
178             }
179         }
180     }
181 
182     /*!
183         @brief      JPEGに埋め込む撮影日時情報を登録します。
184 
185                     この情報は、IFD0 の DateTime と、ExifIFD の DateTimeOriginal タグ、DateTimeDigitized タグとして登録されます。
186                     デフォルトは未登録で、この場合はエンコード関数が内部で @ref GetDateTimeNow を呼び、現在時刻を登録します。
187 
188                     本関数は、エンコード関数を呼ぶ前に呼んでください。
189                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
190                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
191                     他にも、引数 pBuffer にNULLを指定するか、
192                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
193 
194         @param[in]  pBuffer             日時情報を指定します。
195                                         文字列は「YYYY:MM:DD HH:MM:DD」+0x00 の 20 文字としてください。<BR>
196                                         NULLを指定するとクリアします。
197 
198         @return     なし。
199      */
SetDateTime(const char * pBuffer)200     void SetDateTime(const char* pBuffer)
201     {
202         if (m_Initialized)
203         {
204             if (pBuffer)
205             {
206                 memcpy(m_TemporarySetting.dateTimeBuffer, pBuffer, sizeof(m_TemporarySetting.dateTimeBuffer));
207                 m_TemporarySetting.dateTimeBuffer[sizeof(m_TemporarySetting.dateTimeBuffer) - 1] = '\0';
208                 m_TemporarySetting.isDateTimeSet = true;
209             }
210             else
211             {
212                 m_TemporarySetting.isDateTimeSet = false;
213             }
214         }
215     }
216 
217     /*!
218         @brief      現在日時を取得し、@ref SetDateTime の引数に指定できる文字列を作成します。
219 
220                     現在日時の取得には @ref nn::fnd::DateTime::GetNow を使っています。
221 
222         @param[out] pBuffer             日時情報を格納するバッファを指定します。
223                                         バッファのバイト数は @ref DATE_TIME_SIZE (20) です。
224 
225         @return     なし。
226      */
227     static void GetDateTimeNow(char* pBuffer);
228 
229     /*!
230         @brief      JPEGのExif IFDに埋め込む、ソフトウェア名を登録します。
231 
232                     この情報は、IFD0 の Software タグとして登録されます。
233                     デフォルトは未登録です。
234 
235                     本関数は、エンコード関数を呼ぶ前に呼んでください。
236                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
237                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
238                     他にも、引数 pBuffer にNULLを指定するか、
239                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
240 
241         @param[in]  pBuffer             ソフトウェア名を指定します。
242 
243         @return     なし。
244      */
SetSoftware(const char * pBuffer)245     void SetSoftware(const char* pBuffer)
246     {
247         if (m_Initialized)
248         {
249             m_TemporarySetting.pSoftware = pBuffer;
250         }
251     }
252 
253     /*!
254         @brief      JPEGのメーカーノート部分に埋め込む各種データを登録します。
255 
256                     埋め込まれたデータを取得するためには、デコードあるいはExif情報の抽出を行った後、
257                     @ref JpegMpDecoder::GetLastUserMakerNotePointer および @ref JpegMpDecoder::GetLastUserMakerNoteSize を呼んでください。
258 
259                     ・登録できる最大サイズについて<BR>
260                       メーカーノートに登録できるデータのサイズは、APP1セグメント全体のサイズに依存します。
261                       メーカーノートはExifに含まれるため、APP1セグメントの一部となりますが、このAPP1セグメントは0xFFFFまでのサイズしか扱えないようになっています。
262                       そのため、サムネイル等のAPP1領域のデータサイズによって、メーカーノートに埋め込めるデータのサイズは変動することになります。
263                       (目安として 640x480の画像をサムネイル付き、YUV422、クオリティ90でエンコードする場合、トータル 0xE000 以下までのサイズにすることをお勧めします。)
264 
265                     本関数は、エンコード関数を呼ぶ前に呼んでください。
266                     埋め込むデータはエンコード関数終了まで破棄しないでください。
267                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
268                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
269                     他にも、引数 pBuffer にNULLを指定するか、size に0を指定するか、
270                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
271 
272         @param[in]  pBuffer             埋め込むデータを指定します。
273                                         NULLを指定するとクリアします。
274 
275         @param[in]  size                埋め込むデータのバイト数を指定します。
276                                         0を指定するとクリアします。
277 
278         @return     なし。
279      */
280     void SetUserMakerNote(const u8* pBuffer, size_t size);
281 
282     /*!
283         @brief      JPEGのExif IFDに埋め込む、画像ユニークIDを登録します。
284 
285                     埋め込まれたデータを取得するためには、デコードあるいはExif情報の抽出を行った後、
286                     @ref JpegMpDecoder::GetLastImageUid を呼んでください。
287 
288                     MPフォーマットを使用する場合、@ref StartMpEncoderFirst で「個別画像ユニークIDリストを付加する」と指定すると、
289                     @ref StartMpEncoderNext 呼び出し毎に、本関数で登録したIDが個別画像ユニークIDとしてコピーされます。
290                     (先頭画像を除く)
291 
292                     本関数は、エンコード関数を呼ぶ前に呼んでください。
293                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
294                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
295                     他にも、引数 pBuffer にNULLを指定するか、
296                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
297 
298         @param[in]  pBuffer             画像ユニークIDを指定します。<BR>
299                                         文字列は128ビットの整数値を16進数表記したASCII文字列(32文字)で、バイト数は末尾の '\0' を含み @ref IMAGE_UID_SIZE (33) バイトです。<BR>
300                                         NULLを指定するとクリアします。
301 
302         @return     なし。
303      */
SetImageUid(const char * pBuffer)304     void SetImageUid(const char* pBuffer)
305     {
306         if (m_Initialized)
307         {
308             if (pBuffer)
309             {
310                 memcpy(m_TemporarySetting.imageUidBuffer, pBuffer, sizeof(m_TemporarySetting.imageUidBuffer));
311                 m_TemporarySetting.imageUidBuffer[sizeof(m_TemporarySetting.imageUidBuffer) - 1] = '\0';
312                 m_TemporarySetting.isImageUidSet = true;
313             }
314             else
315             {
316                 m_TemporarySetting.isImageUidSet = false;
317             }
318         }
319     }
320 
321     /*!
322         @brief      JPEGのExif IFDに埋め込む、画像方向を登録します。
323 
324                     この情報は、IFD0 の Orientation タグとして登録されます。
325                     デフォルトは未登録です。
326 
327                     本関数は、エンコード関数を呼ぶ前に呼んでください。
328                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
329                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
330                     他にも、@ref ClearOrientation を呼ぶか、
331                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
332 
333         @param[in]  orientation         画像方向(1から8まで)を指定します。
334 
335         @return     なし。
336      */
SetOrientation(u16 orientation)337     void SetOrientation(u16 orientation)
338     {
339         if (m_Initialized)
340         {
341             m_TemporarySetting.orientation = orientation;
342             m_TemporarySetting.isOrientationSet = true;
343         }
344     }
345 
346     /*!
347         @brief      JPEGのExif IFDに画像方向を埋め込まないよう指示します。(デフォルト動作)
348 
349         @return     なし。
350      */
ClearOrientation()351     void ClearOrientation()
352     {
353         if (m_Initialized)
354         {
355             m_TemporarySetting.isOrientationSet = false;
356         }
357     }
358 
359     // リファレンスは追って作成します。
360     // GPS情報のエンコードは、GpsData構造体を初期化して、登録したい情報をSetGps*()で構造体へ設定します。
361     // 最後に、構造体を @ref SetGpsData で登録します。
InitializeGpsData(GpsData * pGps)362     static void InitializeGpsData(GpsData* pGps)
363     {
364         memset(pGps, 0, sizeof(*pGps));
365         // GPSタグのバージョン 2.2。
366         pGps->versionId[0] = 2;
367         pGps->versionId[1] = 2;
368         pGps->isVersionIdValid = true;
369     }
370 
371     // 本関数は、エンコード関数を呼ぶ前に呼んでください。
372     // 埋め込むデータはエンコード関数終了まで破棄しないでください。
373     // エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
374     // 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
375     // 他にも、引数 pGps にNULLを指定するか、@ref ClearGpsData を呼ぶか、
376     // @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
377     // @ref StartMpEncoderLR では両方の画像に登録されます。
SetGpsData(const GpsData * pGps)378     void SetGpsData(const GpsData* pGps)
379     {
380         if (m_Initialized)
381         {
382             m_TemporarySetting.pGpsData = pGps;
383         }
384     }
385 
386     // JPEGにGPS情報を埋め込まないよう指示します。(デフォルト動作)
ClearGpsData()387     void ClearGpsData() { SetGpsData(NULL); }
388 
SetGpsVersionId(GpsData * pGps,const u8 * pVersionId)389     static void SetGpsVersionId(GpsData* pGps, const u8* pVersionId)
390     {
391         NN_ASSERT(pGps);
392 
393         if (pVersionId)
394         {
395             memcpy(pGps->versionId, pVersionId, sizeof(pGps->versionId));
396             pGps->isVersionIdValid = true;
397         }
398         else
399         {
400             pGps->isVersionIdValid = false;
401         }
402     }
403 
ClearGpsVersionId(GpsData * pGps)404     static void ClearGpsVersionId(GpsData* pGps) { SetGpsVersionId(pGps, NULL); }
405 
SetGpsLatitude(GpsData * pGps,char ref,const Rational * pValue)406     static void SetGpsLatitude(GpsData* pGps, char ref, const Rational* pValue)
407     {
408         NN_ASSERT(pGps);
409 
410         pGps->latitudeRef[0] = ref;
411         pGps->latitudeRef[1] = '\0';
412 
413         if (pValue)
414         {
415             memcpy(pGps->latitude, pValue, sizeof(pGps->latitude));
416             pGps->isLatitudeValid = true;
417         }
418         else
419         {
420             pGps->isLatitudeValid = false;
421         }
422     }
423 
ClearGpsLatitude(GpsData * pGps)424     static void ClearGpsLatitude(GpsData* pGps) { SetGpsLatitude(pGps, '\0', NULL); }
425 
SetGpsLongitude(GpsData * pGps,char ref,const Rational * pValue)426     static void SetGpsLongitude(GpsData* pGps, char ref, const Rational* pValue)
427     {
428         NN_ASSERT(pGps);
429 
430         pGps->longitudeRef[0] = ref;
431         pGps->longitudeRef[1] = '\0';
432 
433         if (pValue)
434         {
435             memcpy(pGps->longitude, pValue, sizeof(pGps->longitude));
436             pGps->isLongitudeValid = true;
437         }
438         else
439         {
440             pGps->isLongitudeValid = false;
441         }
442     }
443 
ClearGpsLongitude(GpsData * pGps)444     static void ClearGpsLongitude(GpsData* pGps) { SetGpsLongitude(pGps, '\0', NULL); }
445 
SetGpsAltitude(GpsData * pGps,u8 ref,const Rational * pValue)446     static void SetGpsAltitude(GpsData* pGps, u8 ref, const Rational* pValue)
447     {
448         NN_ASSERT(pGps);
449 
450         if (pValue)
451         {
452             pGps->altitudeRef = ref;
453             memcpy(&pGps->altitude, pValue, sizeof(pGps->altitude));
454             pGps->isAltitudeRefValid = pGps->isAltitudeValid = true;
455         }
456         else
457         {
458             pGps->isAltitudeRefValid = pGps->isAltitudeValid = false;
459         }
460     }
461 
ClearGpsAltitude(GpsData * pGps)462     static void ClearGpsAltitude(GpsData* pGps) { SetGpsAltitude(pGps, 0, NULL); }
463 
SetGpsTimeStamp(GpsData * pGps,const Rational * pValue)464     static void SetGpsTimeStamp(GpsData* pGps, const Rational* pValue)
465     {
466         NN_ASSERT(pGps);
467 
468         if (pValue)
469         {
470             memcpy(pGps->timeStamp, pValue, sizeof(pGps->timeStamp));
471             pGps->isTimeStampValid = true;
472         }
473         else
474         {
475             pGps->isTimeStampValid = false;
476         }
477     }
478 
ClearGpsTimeStamp(GpsData * pGps)479     static void ClearGpsTimeStamp(GpsData* pGps) { SetGpsTimeStamp(pGps, NULL); }
480 
SetGpsSatellites(GpsData * pGps,const char * pSatellites)481     static void SetGpsSatellites(GpsData* pGps, const char* pSatellites)
482     {
483         NN_ASSERT(pGps);
484 
485         pGps->pSatellites = pSatellites;
486     }
487 
ClearGpsSatellites(GpsData * pGps)488     static void ClearGpsSatellites(GpsData* pGps) { SetGpsSatellites(pGps, NULL); }
489 
SetGpsStatus(GpsData * pGps,char status)490     static void SetGpsStatus(GpsData* pGps, char status)
491     {
492         NN_ASSERT(pGps);
493 
494         pGps->status[0] = status;
495         pGps->status[1] = '\0';
496     }
497 
ClearGpsStatus(GpsData * pGps)498     static void ClearGpsStatus(GpsData* pGps) { SetGpsStatus(pGps, '\0'); }
499 
SetGpsMeasureMode(GpsData * pGps,char measureMode)500     static void SetGpsMeasureMode(GpsData* pGps, char measureMode)
501     {
502         NN_ASSERT(pGps);
503 
504         pGps->measureMode[0] = measureMode;
505         pGps->measureMode[1] = '\0';
506     }
507 
ClearGpsMeasureMode(GpsData * pGps)508     static void ClearGpsMeasureMode(GpsData* pGps) { SetGpsMeasureMode(pGps, '\0'); }
509 
SetGpsDop(GpsData * pGps,const Rational * pValue)510     static void SetGpsDop(GpsData* pGps, const Rational* pValue)
511     {
512         NN_ASSERT(pGps);
513 
514         if (pValue)
515         {
516             memcpy(&pGps->dop, pValue, sizeof(pGps->dop));
517             pGps->isDopValid = true;
518         }
519         else
520         {
521             pGps->isDopValid = false;
522         }
523     }
524 
ClearGpsDop(GpsData * pGps)525     static void ClearGpsDop(GpsData* pGps) { SetGpsDop(pGps, NULL); }
526 
SetGpsSpeed(GpsData * pGps,char ref,const Rational * pValue)527     static void SetGpsSpeed(GpsData* pGps, char ref, const Rational* pValue)
528     {
529         NN_ASSERT(pGps);
530 
531         pGps->speedRef[0] = ref;
532         pGps->speedRef[1] = '\0';
533 
534         if (pValue)
535         {
536             memcpy(&pGps->speed, pValue, sizeof(pGps->speed));
537             pGps->isSpeedValid = true;
538         }
539         else
540         {
541             pGps->isSpeedValid = false;
542         }
543     }
544 
ClearGpsSpeed(GpsData * pGps)545     static void ClearGpsSpeed(GpsData* pGps) { SetGpsSpeed(pGps, '\0', NULL); }
546 
SetGpsTrack(GpsData * pGps,char ref,const Rational * pValue)547     static void SetGpsTrack(GpsData* pGps, char ref, const Rational* pValue)
548     {
549         NN_ASSERT(pGps);
550 
551         pGps->trackRef[0] = ref;
552         pGps->trackRef[1] = '\0';
553 
554         if (pValue)
555         {
556             memcpy(&pGps->track, pValue, sizeof(pGps->track));
557             pGps->isTrackValid = true;
558         }
559         else
560         {
561             pGps->isTrackValid = false;
562         }
563     }
564 
ClearGpsTrack(GpsData * pGps)565     static void ClearGpsTrack(GpsData* pGps) { SetGpsTrack(pGps, '\0', NULL); }
566 
SetGpsImgDirection(GpsData * pGps,char ref,const Rational * pValue)567     static void SetGpsImgDirection(GpsData* pGps, char ref, const Rational* pValue)
568     {
569         NN_ASSERT(pGps);
570 
571         pGps->imgDirectionRef[0] = ref;
572         pGps->imgDirectionRef[1] = '\0';
573 
574         if (pValue)
575         {
576             memcpy(&pGps->imgDirection, pValue, sizeof(pGps->imgDirection));
577             pGps->isImgDirectionValid = true;
578         }
579         else
580         {
581             pGps->isImgDirectionValid = false;
582         }
583     }
584 
ClearGpsImgDirection(GpsData * pGps)585     static void ClearGpsImgDirection(GpsData* pGps) { SetGpsImgDirection(pGps, '\0', NULL); }
586 
SetGpsMapDatum(GpsData * pGps,const char * pMapDatum)587     static void SetGpsMapDatum(GpsData* pGps, const char* pMapDatum)
588     {
589         NN_ASSERT(pGps);
590 
591         pGps->pMapDatum = pMapDatum;
592     }
593 
ClearGpsMapDatum(GpsData * pGps)594     static void ClearGpsMapDatum(GpsData* pGps) { SetGpsMapDatum(pGps, NULL); }
595 
SetGpsDestLatitude(GpsData * pGps,char ref,const Rational * pValue)596     static void SetGpsDestLatitude(GpsData* pGps, char ref, const Rational* pValue)
597     {
598         NN_ASSERT(pGps);
599 
600         pGps->destLatitudeRef[0] = ref;
601         pGps->destLatitudeRef[1] = '\0';
602 
603         if (pValue)
604         {
605             memcpy(pGps->destLatitude, pValue, sizeof(pGps->destLatitude));
606             pGps->isDestLatitudeValid = true;
607         }
608         else
609         {
610             pGps->isDestLatitudeValid = false;
611         }
612     }
613 
ClearGpsDestLatitude(GpsData * pGps)614     static void ClearGpsDestLatitude(GpsData* pGps) { SetGpsDestLatitude(pGps, '\0', NULL); }
615 
SetGpsDestLongitude(GpsData * pGps,char ref,const Rational * pValue)616     static void SetGpsDestLongitude(GpsData* pGps, char ref, const Rational* pValue)
617     {
618         NN_ASSERT(pGps);
619 
620         pGps->destLongitudeRef[0] = ref;
621         pGps->destLongitudeRef[1] = '\0';
622 
623         if (pValue)
624         {
625             memcpy(pGps->destLongitude, pValue, sizeof(pGps->destLongitude));
626             pGps->isDestLongitudeValid = true;
627         }
628         else
629         {
630             pGps->isDestLongitudeValid = false;
631         }
632     }
633 
ClearGpsDestLongitude(GpsData * pGps)634     static void ClearGpsDestLongitude(GpsData* pGps) { SetGpsDestLongitude(pGps, '\0', NULL); }
635 
SetGpsDestBearing(GpsData * pGps,char ref,const Rational * pValue)636     static void SetGpsDestBearing(GpsData* pGps, char ref, const Rational* pValue)
637     {
638         NN_ASSERT(pGps);
639 
640         pGps->destBearingRef[0] = ref;
641         pGps->destBearingRef[1] = '\0';
642 
643         if (pValue)
644         {
645             memcpy(&pGps->destBearing, pValue, sizeof(pGps->destBearing));
646             pGps->isDestBearingValid = true;
647         }
648         else
649         {
650             pGps->isDestBearingValid = false;
651         }
652     }
653 
ClearGpsDestBearing(GpsData * pGps)654     static void ClearGpsDestBearing(GpsData* pGps) { SetGpsDestBearing(pGps, '\0', NULL); }
655 
SetGpsDestDistance(GpsData * pGps,char ref,const Rational * pValue)656     static void SetGpsDestDistance(GpsData* pGps, char ref, const Rational* pValue)
657     {
658         NN_ASSERT(pGps);
659 
660         pGps->destDistanceRef[0] = ref;
661         pGps->destDistanceRef[1] = '\0';
662 
663         if (pValue)
664         {
665             memcpy(&pGps->destDistance, pValue, sizeof(pGps->destDistance));
666             pGps->isDestDistanceValid = true;
667         }
668         else
669         {
670             pGps->isDestDistanceValid = false;
671         }
672     }
673 
ClearGpsDestDistance(GpsData * pGps)674     static void ClearGpsDestDistance(GpsData* pGps) { SetGpsDestDistance(pGps, '\0', NULL); }
675 
SetGpsProcessingMethod(GpsData * pGps,const u8 * pProcessingMethod,size_t processingMethodSize)676     static void SetGpsProcessingMethod(GpsData* pGps, const u8* pProcessingMethod, size_t processingMethodSize)
677     {
678         NN_ASSERT(pGps);
679 
680         if (pProcessingMethod && processingMethodSize)
681         {
682             pGps->pProcessingMethod    = pProcessingMethod;
683             pGps->processingMethodSize = processingMethodSize;
684         }
685         else
686         {
687             pGps->pProcessingMethod    = NULL;
688             pGps->processingMethodSize = 0;
689         }
690     }
691 
ClearGpsProcessingMethod(GpsData * pGps)692     static void ClearGpsProcessingMethod(GpsData* pGps) { SetGpsProcessingMethod(pGps, NULL, 0); }
693 
SetGpsAreaInformation(GpsData * pGps,const u8 * pAreaInformation,size_t areaInformationSize)694     static void SetGpsAreaInformation(GpsData* pGps, const u8* pAreaInformation, size_t areaInformationSize)
695     {
696         NN_ASSERT(pGps);
697 
698         if (pAreaInformation && areaInformationSize)
699         {
700             pGps->pAreaInformation    = pAreaInformation;
701             pGps->areaInformationSize = areaInformationSize;
702         }
703         else
704         {
705             pGps->pAreaInformation    = NULL;
706             pGps->areaInformationSize = 0;
707         }
708     }
709 
ClearGpsAreaInformation(GpsData * pGps)710     static void ClearGpsAreaInformation(GpsData* pGps) { SetGpsAreaInformation(pGps, NULL, 0); }
711 
SetGpsDateStamp(GpsData * pGps,const char * pDateStamp)712     static void SetGpsDateStamp(GpsData* pGps, const char* pDateStamp)
713     {
714         NN_ASSERT(pGps);
715 
716         pGps->pDateStamp = pDateStamp;
717     }
718 
ClearGpsDateStamp(GpsData * pGps)719     static void ClearGpsDateStamp(GpsData* pGps) { SetGpsDateStamp(pGps, NULL); }
720 
SetGpsDifferential(GpsData * pGps,u16 differential)721     static void SetGpsDifferential(GpsData* pGps, u16 differential)
722     {
723         NN_ASSERT(pGps);
724 
725         pGps->differential = differential;
726         pGps->isDifferentialValid = true;
727     }
728 
ClearGpsDifferential(GpsData * pGps)729     static void ClearGpsDifferential(GpsData* pGps)
730     {
731         NN_ASSERT(pGps);
732 
733         pGps->isDifferentialValid = false;
734     }
735 
736     /*!
737         @brief      JPEGエンコードを実行します。
738 
739                     本関数でエンコードできる画像の縦横サイズは画像の出力形式(引数 dstPixelSampling)によって変わります。<BR>
740                     @ref PIXEL_SAMPLING_YUV444 を指定した場合は、縦横サイズがそれぞれ8の倍数である必要があります。<BR>
741                     @ref PIXEL_SAMPLING_YUV420 を指定した場合は、縦横サイズがそれぞれ16の倍数である必要があります。<BR>
742                     @ref PIXEL_SAMPLING_YUV422 を指定した場合は、縦サイズが8の倍数、横サイズが16の倍数である必要があります。
743 
744         @param[out] dst                 エンコード結果を格納するバッファを指定します。
745 
746         @param[in]  limit               dstのバイト数を指定します。
747                                         このバイト数を超えるとエンコードに失敗します。
748 
749         @param[in]  src                 エンコードする画像データバッファを指定します。
750                                         4バイトアラインメントが必要です。
751 
752         @param[in]  width               画像の横幅(pixel)を指定します。(65536未満)
753 
754         @param[in]  height              画像の縦幅(pixel)を指定します。(65536未満)
755 
756         @param[in]  quality             エンコードのクオリティを指定します。<BR>
757                                         1~100 まで指定可能であり、100 に近づくほど高画質になりサイズが大きくなります。
758 
759         @param[in]  dstPixelSampling    画像の出力形式(画素サンプリング)を指定します。
760 
761         @param[in]  srcPixelFormat      エンコードする画像の入力ピクセルフォーマットを指定します。
762 
763         @param[in]  addThumbnail        サムネイルを付加するかどうかを指定します。
764 
765         @return     成功した場合、生成されたJPEGフォーマットデータのバイト数を返します。
766                     失敗した場合、0を返します。<BR>
767                     失敗の原因は @ref GetLastError で取得できます。
768      */
769     size_t StartJpegEncoder(u8* dst,
770                             size_t limit,
771                             const void* src,
772                             u32 width,
773                             u32 height,
774                             u32 quality,
775                             PixelSampling dstPixelSampling,
776                             PixelFormat srcPixelFormat,
777                             bool addThumbnail);
778 
779     /*!
780         @brief      JPEGエンコードを2枚の画像に対して実行し、Extended MPフォーマット(立体視用)で格納します。
781 
782                     最初に左目用画像をエンコードし、MPフォーマットの先頭画像(かつ代表画像)として格納します。
783                     成功すれば、続けて右目用画像をエンコードし格納します。
784                     本関数では、左目用画像の視点番号は1、基準視点番号も1です。
785                     右目用画像の視点番号は2です。
786 
787                     本関数でエンコードできる画像の縦横サイズは画像の出力形式(引数 dstPixelSampling)によって変わります。
788                     @ref StartJpegEncoder と同じです。
789 
790                     輻輳角および基線長はデフォルト値 {0xFFFFFFFF,0xFFFFFFFF} になります。
791 
792                     以下の各種データ登録関数を呼んでも効果がありません。<BR>
793                       @ref SetUserMakerNote 、@ref SetImageUid 、
794                       @ref SetMpTypeFlags 、@ref SetMpIndividualNum 、
795                       @ref SetMpPanOrientation 、@ref SetMpPanOverlapH 、@ref SetMpPanOverlapV 、
796                       @ref SetMpBaseViewpointNum 、@ref SetMpConvergenceAngle 、@ref SetMpBaselineLength 、@ref SetMpVerticalDivergence 、
797                       @ref SetMpAxisDistanceX 、@ref SetMpAxisDistanceY 、@ref SetMpAxisDistanceZ 、
798                       @ref SetMpYawAngle 、@ref SetMpPitchAngle 、@ref SetMpRollAngle
799 
800                     以下の関数を呼んだ場合、指定は両方の画像に対して有効で、同一値が登録されます。
801                     (@ref SetDateTime を呼ばなかった場合は先頭画像のエンコード時に現在日時を取得し、2枚の画像の日時情報は同じになります。)<BR>
802                       @ref SetThumbnailSize 、@ref SetInputBufferWidth 、@ref SetDateTime 、@ref SetSoftware 、
803                       @ref SetOrientation 、@ref SetGpsData
804 
805         @param[out] dst                 エンコード結果を格納するバッファを指定します。
806 
807         @param[in]  limit               dstのバイト数を指定します。
808                                         このバイト数を超えるとエンコードに失敗します。
809 
810         @param[in]  srcL                エンコードする左目用画像データバッファを指定します。
811                                         4バイトアラインメントが必要です。
812 
813         @param[in]  srcR                エンコードする右目用画像データバッファを指定します。
814                                         4バイトアラインメントが必要です。
815 
816         @param[in]  width               画像の横幅(pixel)を指定します。(65536未満)
817                                         サムネイル以外の左右画像で共通です。
818 
819         @param[in]  height              画像の縦幅(pixel)を指定します。(65536未満)
820                                         サムネイル以外の左右画像で共通です。
821 
822         @param[in]  quality             エンコードのクオリティを指定します。<BR>
823                                         1~100 まで指定可能であり、100 に近づくほど高画質になりサイズが大きくなります。<BR>
824                                         サムネイル以外の左右画像で共通です。
825 
826         @param[in]  dstPixelSampling    画像の出力形式(画素サンプリング)を指定します。
827                                         サムネイル以外の左右画像で共通です。
828 
829         @param[in]  srcPixelFormat      エンコードする画像の入力ピクセルフォーマットを指定します。
830                                         全ての画像で共通です。
831 
832         @param[in]  addThumbnailL       左目用画像へサムネイルを付加するかどうかを指定します。
833 
834         @param[in]  addThumbnailR       右目用画像へサムネイルを付加するかどうかを指定します。
835 
836         @return     成功した場合、生成されたMPフォーマットデータのバイト数を返します。
837                     失敗した場合、0を返します。<BR>
838                     失敗の原因は @ref GetLastError で取得できます。
839      */
840     size_t StartMpEncoderLR(u8* dst,
841                             size_t limit,
842                             const void* srcL,
843                             const void* srcR,
844                             u32 width,
845                             u32 height,
846                             u32 quality,
847                             PixelSampling dstPixelSampling,
848                             PixelFormat srcPixelFormat,
849                             bool addThumbnailL,
850                             bool addThumbnailR);
851 
852     /*!
853         @brief      MPエントリに埋め込む、個別画像種別管理情報の各種フラグと、従属画像エントリ番号を登録します。
854 
855                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
856                     @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます)
857 
858                     個別画像種別管理情報のフィールドのうち、「従属親画像フラグ」、「従属子画像フラグ」、「代表画像フラグ」
859                     を指定できます。
860                     他のフィールドのうち、「予約(0)」、「データ形式(0: JPEG)」はライブラリで固定されており、指定できません。
861                     「種別コード」は @ref StartMpEncoderFirst で指定します。
862 
863                     本関数を呼ばずに @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使っても問題ありません。
864                     デフォルトで、「従属親画像フラグ=0」、「従属子画像フラグ=0」、
865                     「代表画像フラグ=先頭画像のみ1、他は0」となります。
866 
867                     デフォルト動作の詳細は以下の通りです。<BR>
868                       1. 本関数を呼ばずに @ref StartMpEncoderFirst を使った場合、
869                          この画像(先頭画像)が代表画像(代表画像フラグ=1)となります。<BR>
870                       2. 本関数を呼ばずに @ref StartMpEncoderNext を使った場合、
871                          まだ代表画像が存在していなければ、この画像が代表画像となります。
872                          代表画像が存在していれば、この画像は代表画像フラグ=0となります。
873 
874                     本関数は、エンコード関数を呼ぶ前に呼んでください。
875                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
876                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
877                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
878 
879         @param[in]  flags               @ref MpTypeFlag を単独あるいは論理和で指定します。0も指定できます。<BR>
880                                         @ref MP_TYPE_FLAG_REPRESENTATIVE_IMAGE (代表画像フラグ)をセットしても、
881                                         既に代表画像が存在していれば無視されます。<BR>
882                                         デフォルトは0です。
883 
884         @param[in]  image1              従属画像1エントリ番号を指定します。
885                                         デフォルトは0です。
886 
887         @param[in]  image2              従属画像2エントリ番号を指定します。
888                                         デフォルトは0です。
889 
890         @return     なし。
891      */
892     void SetMpTypeFlags(u32 flags = 0, u16 image1 = 0, u16 image2 = 0)
893     {
894         if (m_Initialized)
895         {
896             m_TemporarySetting.isDependentParent = (flags & MP_TYPE_FLAG_DEPENDENT_IMAGE_PARENT) ? true : false;
897             m_TemporarySetting.isDependentChild  = (flags & MP_TYPE_FLAG_DEPENDENT_IMAGE_CHILD)  ? true : false;
898             m_TemporarySetting.isRepresentativeSet = true;
899             m_TemporarySetting.isRepresentative  = (flags & MP_TYPE_FLAG_REPRESENTATIVE_IMAGE)   ? true : false;
900             m_TemporarySetting.dependentImage1EntryNum = image1;
901             m_TemporarySetting.dependentImage2EntryNum = image2;
902         }
903     }
904 
905     /*!
906         @brief      MP個別情報IFDに埋め込む、個別画像番号を登録します。
907 
908                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
909                     @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます)
910 
911                     本関数を呼ばない場合、ライブラリがデフォルト値を登録します。
912                     デフォルト値は @ref StartMpEncoderFirst を呼ぶと1に初期化され、エンコード関数終了後、1ずつ増加します。
913 
914                     本関数は、エンコード関数を呼ぶ前に呼んでください。
915                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
916                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
917                     他にも、@ref ClearMpIndividualNum を呼ぶか、
918                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
919 
920         @param[in]  value               個別画像番号を指定します。
921 
922         @return     なし。
923      */
SetMpIndividualNum(u32 value)924     void SetMpIndividualNum(u32 value)
925     {
926         if (m_Initialized)
927         {
928             m_TemporarySetting.mpAttribute.mpIndividualNum = value;
929             m_TemporarySetting.mpAttribute.isMpIndividualNumValid = true;
930         }
931     }
932 
933     /*!
934         @brief      MP個別情報IFDに埋め込む、個別画像番号をデフォルト値に戻します。
935 
936         @return     なし。
937      */
ClearMpIndividualNum()938     void ClearMpIndividualNum()
939     {
940         if (m_Initialized)
941         {
942             m_TemporarySetting.mpAttribute.isMpIndividualNumValid = false;
943         }
944     }
945 
946     /*!
947         @brief      MP個別情報IFDに埋め込む、画像配置を登録します。
948 
949                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
950                     @ref StartMpEncoderLR を使う場合には無効です。
951 
952                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像)
953                     でない場合、値は埋め込まれません。
954 
955                     本関数は、エンコード関数を呼ぶ前に呼んでください。
956                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
957                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
958                     他にも、@ref ClearMpPanOrientation を呼ぶか、
959                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
960 
961         @param[in]  value               画像配置を指定します。
962 
963         @return     なし。
964      */
SetMpPanOrientation(u32 value)965     void SetMpPanOrientation(u32 value)
966     {
967         if (m_Initialized)
968         {
969             m_TemporarySetting.mpAttribute.panOrientation = value;
970             m_TemporarySetting.mpAttribute.isPanOrientationValid = true;
971         }
972     }
973 
974     /*!
975         @brief      MP個別情報IFDに画像配置を埋め込まないよう指示します。(デフォルト動作)
976 
977         @return     なし。
978      */
ClearMpPanOrientation()979     void ClearMpPanOrientation()
980     {
981         if (m_Initialized)
982         {
983             m_TemporarySetting.mpAttribute.isPanOrientationValid = false;
984         }
985     }
986 
987     /*!
988         @brief      MP個別情報IFDに埋め込む、水平オーバーラップを登録します。
989 
990                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
991                     @ref StartMpEncoderLR を使う場合には無効です。
992 
993                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像)
994                     でない場合、値は埋め込まれません。
995 
996                     本関数は、エンコード関数を呼ぶ前に呼んでください。
997                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
998                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
999                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpPanOverlapH を呼ぶか、
1000                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1001 
1002         @param[in]  pValue              水平オーバーラップを指定します。
1003                                         NULLを指定するとクリアします。
1004 
1005         @return     なし。
1006      */
SetMpPanOverlapH(const Rational * pValue)1007     void SetMpPanOverlapH(const Rational* pValue)
1008     {
1009         if (m_Initialized)
1010         {
1011             if (pValue)
1012             {
1013                 m_TemporarySetting.mpAttribute.panOverlapH = *pValue;
1014                 m_TemporarySetting.mpAttribute.isPanOverlapHValid = true;
1015             }
1016             else
1017             {
1018                 m_TemporarySetting.mpAttribute.isPanOverlapHValid = false;
1019             }
1020         }
1021     }
1022 
1023     /*!
1024         @brief      MP個別情報IFDに水平オーバーラップを埋め込まないよう指示します。(デフォルト動作)
1025 
1026         @return     なし。
1027      */
ClearMpPanOverlapH()1028     void ClearMpPanOverlapH() { SetMpPanOverlapH(NULL); }
1029 
1030     /*!
1031         @brief      MP個別情報IFDに埋め込む、垂直オーバーラップを登録します。
1032 
1033                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1034                     @ref StartMpEncoderLR を使う場合には無効です。
1035 
1036                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像)
1037                     でない場合、値は埋め込まれません。
1038 
1039                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1040                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1041                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1042                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpPanOverlapV を呼ぶか、
1043                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1044 
1045         @param[in]  pValue              垂直オーバーラップを指定します。
1046                                         NULLを指定するとクリアします。
1047 
1048         @return     なし。
1049      */
SetMpPanOverlapV(const Rational * pValue)1050     void SetMpPanOverlapV(const Rational* pValue)
1051     {
1052         if (m_Initialized)
1053         {
1054             if (pValue)
1055             {
1056                 m_TemporarySetting.mpAttribute.panOverlapV = *pValue;
1057                 m_TemporarySetting.mpAttribute.isPanOverlapVValid = true;
1058             }
1059             else
1060             {
1061                 m_TemporarySetting.mpAttribute.isPanOverlapVValid = false;
1062             }
1063         }
1064     }
1065 
1066     /*!
1067         @brief      MP個別情報IFDに垂直オーバーラップを埋め込まないよう指示します。(デフォルト動作)
1068 
1069         @return     なし。
1070      */
ClearMpPanOverlapV()1071     void ClearMpPanOverlapV() { SetMpPanOverlapV(NULL); }
1072 
1073     /*!
1074         @brief      MP個別情報IFDに埋め込む、基準視点番号を登録します。
1075 
1076                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1077                     @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます)
1078 
1079                     本関数を呼ばない場合、ライブラリがデフォルト値(1)を登録します。
1080                     ただし、画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像)
1081                     でも @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) でもない場合、
1082                     値は埋め込まれません。
1083 
1084                     基準視点番号は全ての個別画像で同一の値を埋め込む必要があるため、
1085                     本関数は、@ref StartMpEncoderFirst を呼ぶ前に呼んでください。
1086                     @ref StartMpEncoderNext を呼ぶ前に本関数を呼んでも無視されます。
1087 
1088                     全ての個別画像のエンコードが終了後、成功、失敗問わず本関数の指定はクリアされます。
1089                     他にも、@ref ClearMpBaseViewpointNum を呼ぶか、
1090                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1091 
1092         @param[in]  value               基準視点番号を指定します。
1093 
1094         @return     なし。
1095      */
SetMpBaseViewpointNum(u32 value)1096     void SetMpBaseViewpointNum(u32 value)
1097     {
1098         if (m_Initialized)
1099         {
1100             m_TemporarySetting.mpAttribute.baseViewpointNum = value;
1101             m_TemporarySetting.mpAttribute.isBaseViewpointNumValid = true;
1102         }
1103     }
1104 
1105     /*!
1106         @brief      MP個別情報IFDに埋め込む、基準視点番号をデフォルト値に戻します。
1107 
1108         @return     なし。
1109      */
ClearMpBaseViewpointNum()1110     void ClearMpBaseViewpointNum()
1111     {
1112         if (m_Initialized)
1113         {
1114             m_TemporarySetting.mpAttribute.isBaseViewpointNumValid = false;
1115         }
1116     }
1117 
1118     /*!
1119         @brief      MP個別情報IFDに埋め込む、輻輳角を登録します。
1120 
1121                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1122                     @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます)
1123 
1124                     本関数を呼ばない場合、ライブラリがデフォルト値(0xFFFFFFFF/0xFFFFFFFF)を登録します。
1125                     ただし、画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像)
1126                     でない場合、値は埋め込まれません。
1127 
1128                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1129                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1130                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1131                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpConvergenceAngle を呼ぶか、
1132                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1133 
1134         @param[in]  pValue              輻輳角を指定します。
1135                                         NULLを指定するとクリアします。
1136 
1137         @return     なし。
1138      */
SetMpConvergenceAngle(const Srational * pValue)1139     void SetMpConvergenceAngle(const Srational* pValue)
1140     {
1141         if (m_Initialized)
1142         {
1143             if (pValue)
1144             {
1145                 m_TemporarySetting.mpAttribute.convergenceAngle = *pValue;
1146                 m_TemporarySetting.mpAttribute.isConvergenceAngleValid = true;
1147             }
1148             else
1149             {
1150                 m_TemporarySetting.mpAttribute.isConvergenceAngleValid = false;
1151             }
1152         }
1153     }
1154 
1155     /*!
1156         @brief      MP個別情報IFDに埋め込む、輻輳角をデフォルト値に戻します。
1157 
1158         @return     なし。
1159      */
ClearMpConvergenceAngle()1160     void ClearMpConvergenceAngle() { SetMpConvergenceAngle(NULL); }
1161 
1162     /*!
1163         @brief      MP個別情報IFDに埋め込む、基線長を登録します。
1164 
1165                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1166                     @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます)
1167 
1168                     本関数を呼ばない場合、ライブラリがデフォルト値(0xFFFFFFFF/0xFFFFFFFF)を登録します。
1169                     ただし、画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像)
1170                     でない場合、値は埋め込まれません。
1171 
1172                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1173                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1174                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1175                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpBaselineLength を呼ぶか、
1176                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1177 
1178         @param[in]  pValue              基線長を指定します。
1179                                         NULLを指定するとクリアします。
1180 
1181         @return     なし。
1182      */
SetMpBaselineLength(const Rational * pValue)1183     void SetMpBaselineLength(const Rational* pValue)
1184     {
1185         if (m_Initialized)
1186         {
1187             if (pValue)
1188             {
1189                 m_TemporarySetting.mpAttribute.baselineLength = *pValue;
1190                 m_TemporarySetting.mpAttribute.isBaselineLengthValid = true;
1191             }
1192             else
1193             {
1194                 m_TemporarySetting.mpAttribute.isBaselineLengthValid = false;
1195             }
1196         }
1197     }
1198 
1199     /*!
1200         @brief      MP個別情報IFDに埋め込む、基線長をデフォルト値に戻します。
1201 
1202         @return     なし。
1203      */
ClearMpBaselineLength()1204     void ClearMpBaselineLength() { SetMpBaselineLength(NULL); }
1205 
1206     /*!
1207         @brief      MP個別情報IFDに埋め込む、水平からのずれを登録します。
1208 
1209                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1210                     @ref StartMpEncoderLR を使う場合には無効です。
1211 
1212                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像)
1213                     でない場合、値は埋め込まれません。
1214 
1215                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1216                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1217                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1218                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpVerticalDivergence を呼ぶか、
1219                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1220 
1221         @param[in]  pValue              水平からのずれを指定します。
1222                                         NULLを指定するとクリアします。
1223 
1224         @return     なし。
1225      */
SetMpVerticalDivergence(const Srational * pValue)1226     void SetMpVerticalDivergence(const Srational* pValue)
1227     {
1228         if (m_Initialized)
1229         {
1230             if (pValue)
1231             {
1232                 m_TemporarySetting.mpAttribute.verticalDivergence = *pValue;
1233                 m_TemporarySetting.mpAttribute.isVerticalDivergenceValid = true;
1234             }
1235             else
1236             {
1237                 m_TemporarySetting.mpAttribute.isVerticalDivergenceValid = false;
1238             }
1239         }
1240     }
1241 
1242     /*!
1243         @brief      MP個別情報IFDに水平からのずれを埋め込まないよう指示します。(デフォルト動作)
1244 
1245         @return     なし。
1246      */
ClearMpVerticalDivergence()1247     void ClearMpVerticalDivergence() { SetMpVerticalDivergence(NULL); }
1248 
1249     /*!
1250         @brief      MP個別情報IFDに埋め込む、水平軸方向の距離(X)を登録します。
1251 
1252                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1253                     @ref StartMpEncoderLR を使う場合には無効です。
1254 
1255                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像)
1256                     でない場合、値は埋め込まれません。
1257 
1258                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1259                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1260                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1261                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpAxisDistanceX を呼ぶか、
1262                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1263 
1264         @param[in]  pValue              水平軸方向の距離(X)を指定します。
1265                                         NULLを指定するとクリアします。
1266 
1267         @return     なし。
1268      */
SetMpAxisDistanceX(const Srational * pValue)1269     void SetMpAxisDistanceX(const Srational* pValue)
1270     {
1271         if (m_Initialized)
1272         {
1273             if (pValue)
1274             {
1275                 m_TemporarySetting.mpAttribute.axisDistanceX = *pValue;
1276                 m_TemporarySetting.mpAttribute.isAxisDistanceXValid = true;
1277             }
1278             else
1279             {
1280                 m_TemporarySetting.mpAttribute.isAxisDistanceXValid = false;
1281             }
1282         }
1283     }
1284 
1285     /*!
1286         @brief      MP個別情報IFDに水平軸方向の距離(X)を埋め込まないよう指示します。(デフォルト動作)
1287 
1288         @return     なし。
1289      */
ClearMpAxisDistanceX()1290     void ClearMpAxisDistanceX() { SetMpAxisDistanceX(NULL); }
1291 
1292     /*!
1293         @brief      MP個別情報IFDに埋め込む、鉛直軸方向の距離(Y)を登録します。
1294 
1295                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1296                     @ref StartMpEncoderLR を使う場合には無効です。
1297 
1298                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像)
1299                     でない場合、値は埋め込まれません。
1300 
1301                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1302                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1303                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1304                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpAxisDistanceY を呼ぶか、
1305                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1306 
1307         @param[in]  pValue              鉛直軸方向の距離(Y)を指定します。
1308                                         NULLを指定するとクリアします。
1309 
1310         @return     なし。
1311      */
SetMpAxisDistanceY(const Srational * pValue)1312     void SetMpAxisDistanceY(const Srational* pValue)
1313     {
1314         if (m_Initialized)
1315         {
1316             if (pValue)
1317             {
1318                 m_TemporarySetting.mpAttribute.axisDistanceY = *pValue;
1319                 m_TemporarySetting.mpAttribute.isAxisDistanceYValid = true;
1320             }
1321             else
1322             {
1323                 m_TemporarySetting.mpAttribute.isAxisDistanceYValid = false;
1324             }
1325         }
1326     }
1327 
1328     /*!
1329         @brief      MP個別情報IFDに鉛直軸方向の距離(Y)を埋め込まないよう指示します。(デフォルト動作)
1330 
1331         @return     なし。
1332      */
ClearMpAxisDistanceY()1333     void ClearMpAxisDistanceY() { SetMpAxisDistanceY(NULL); }
1334 
1335     /*!
1336         @brief      MP個別情報IFDに埋め込む、視準軸方向の距離(Z)を登録します。
1337 
1338                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1339                     @ref StartMpEncoderLR を使う場合には無効です。
1340 
1341                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像)
1342                     でない場合、値は埋め込まれません。
1343 
1344                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1345                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1346                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1347                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpAxisDistanceZ を呼ぶか、
1348                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1349 
1350         @param[in]  pValue              視準軸方向の距離(Z)を指定します。
1351                                         NULLを指定するとクリアします。
1352 
1353         @return     なし。
1354      */
SetMpAxisDistanceZ(const Srational * pValue)1355     void SetMpAxisDistanceZ(const Srational* pValue)
1356     {
1357         if (m_Initialized)
1358         {
1359             if (pValue)
1360             {
1361                 m_TemporarySetting.mpAttribute.axisDistanceZ = *pValue;
1362                 m_TemporarySetting.mpAttribute.isAxisDistanceZValid = true;
1363             }
1364             else
1365             {
1366                 m_TemporarySetting.mpAttribute.isAxisDistanceZValid = false;
1367             }
1368         }
1369     }
1370 
1371     /*!
1372         @brief      MP個別情報IFDに視準軸方向の距離(Z)を埋め込まないよう指示します。(デフォルト動作)
1373 
1374         @return     なし。
1375      */
ClearMpAxisDistanceZ()1376     void ClearMpAxisDistanceZ() { SetMpAxisDistanceZ(NULL); }
1377 
1378     /*!
1379         @brief      MP個別情報IFDに埋め込む、ヨー角を登録します。
1380 
1381                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1382                     @ref StartMpEncoderLR を使う場合には無効です。
1383 
1384                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像)
1385                     でない場合、値は埋め込まれません。
1386 
1387                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1388                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1389                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1390                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpYawAngle を呼ぶか、
1391                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1392 
1393         @param[in]  pValue              ヨー角を指定します。
1394                                         NULLを指定するとクリアします。
1395 
1396         @return     なし。
1397      */
SetMpYawAngle(const Srational * pValue)1398     void SetMpYawAngle(const Srational* pValue)
1399     {
1400         if (m_Initialized)
1401         {
1402             if (pValue)
1403             {
1404                 m_TemporarySetting.mpAttribute.yawAngle = *pValue;
1405                 m_TemporarySetting.mpAttribute.isYawAngleValid = true;
1406             }
1407             else
1408             {
1409                 m_TemporarySetting.mpAttribute.isYawAngleValid = false;
1410             }
1411         }
1412     }
1413 
1414     /*!
1415         @brief      MP個別情報IFDにヨー角を埋め込まないよう指示します。(デフォルト動作)
1416 
1417         @return     なし。
1418      */
ClearMpYawAngle()1419     void ClearMpYawAngle() { SetMpYawAngle(NULL); }
1420 
1421     /*!
1422         @brief      MP個別情報IFDに埋め込む、ピッチ角を登録します。
1423 
1424                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1425                     @ref StartMpEncoderLR を使う場合には無効です。
1426 
1427                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像)
1428                     でない場合、値は埋め込まれません。
1429 
1430                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1431                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1432                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1433                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpPitchAngle を呼ぶか、
1434                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1435 
1436         @param[in]  pValue              ピッチ角を指定します。
1437                                         NULLを指定するとクリアします。
1438 
1439         @return     なし。
1440      */
SetMpPitchAngle(const Srational * pValue)1441     void SetMpPitchAngle(const Srational* pValue)
1442     {
1443         if (m_Initialized)
1444         {
1445             if (pValue)
1446             {
1447                 m_TemporarySetting.mpAttribute.pitchAngle = *pValue;
1448                 m_TemporarySetting.mpAttribute.isPitchAngleValid = true;
1449             }
1450             else
1451             {
1452                 m_TemporarySetting.mpAttribute.isPitchAngleValid = false;
1453             }
1454         }
1455     }
1456 
1457     /*!
1458         @brief      MP個別情報IFDにピッチ角を埋め込まないよう指示します。(デフォルト動作)
1459 
1460         @return     なし。
1461      */
ClearMpPitchAngle()1462     void ClearMpPitchAngle() { SetMpPitchAngle(NULL); }
1463 
1464     /*!
1465         @brief      MP個別情報IFDに埋め込む、ロール角を登録します。
1466 
1467                     本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。
1468                     @ref StartMpEncoderLR を使う場合には無効です。
1469 
1470                     本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像)
1471                     でない場合、値は埋め込まれません。
1472 
1473                     本関数は、エンコード関数を呼ぶ前に呼んでください。
1474                     エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。
1475                     複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。
1476                     他にも、引数 pValue にNULLを指定するか、@ref ClearMpRollAngle を呼ぶか、
1477                     @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。
1478 
1479         @param[in]  pValue              ロール角を指定します。
1480                                         NULLを指定するとクリアします。
1481 
1482         @return     なし。
1483      */
SetMpRollAngle(const Srational * pValue)1484     void SetMpRollAngle(const Srational* pValue)
1485     {
1486         if (m_Initialized)
1487         {
1488             if (pValue)
1489             {
1490                 m_TemporarySetting.mpAttribute.rollAngle = *pValue;
1491                 m_TemporarySetting.mpAttribute.isRollAngleValid = true;
1492             }
1493             else
1494             {
1495                 m_TemporarySetting.mpAttribute.isRollAngleValid = false;
1496             }
1497         }
1498     }
1499 
1500     /*!
1501         @brief      MP個別情報IFDにロール角を埋め込まないよう指示します。(デフォルト動作)
1502 
1503         @return     なし。
1504      */
ClearMpRollAngle()1505     void ClearMpRollAngle() { SetMpRollAngle(NULL); }
1506 
1507     /*!
1508         @brief      JPEGエンコードを実行し、MPフォーマットの先頭画像として格納します。
1509 
1510                     本関数では1組のMPフォーマットデータ(マルチピクチャオブジェクト、以下「MPO」)
1511                     に含む合計画像数の指定と、先頭画像のエンコードを行います。
1512                     2枚目から合計画像数までのエンコードを行うためには、@ref StartMpEncoderNext を呼んでください。
1513 
1514                     後続の @ref StartMpEncoderNext のエンコード結果に応じて、本関数でエンコードした先頭画像のAPP2
1515                     (MPインデックスIFDやMPエントリ、MP個別情報IFDを含みます)が書き換えられます。
1516                     指定した合計画像数のエンコード途中で失敗した場合や、エンコードを中止した場合は、
1517                     先頭画像からエンコードをやり直す必要があります。
1518 
1519                     @ref StartMpEncoderLR と異なり、@ref SetUserMakerNote 、@ref SetMpTypeFlags 、@ref SetDateTime
1520                     等を呼んで、画像毎に各種データを登録できます。
1521                     2枚目以降に各種データを登録する場合、@ref StartMpEncoderNext を呼ぶ前にそれらの関数を呼ぶ必要があります。
1522 
1523                     また、@ref SetThumbnailSize および @ref SetInputBufferWidth の指定も画像毎になります。
1524                     2枚目以降に指定を行う場合、@ref StartMpEncoderNext を呼ぶ前にそれらの関数を呼ぶ必要があります。
1525 
1526                     本関数でエンコードできる画像の縦横サイズは画像の出力形式(引数 dstPixelSampling)によって変わります。
1527                     @ref StartJpegEncoder と同じです。
1528 
1529                     引数 typeCode に @ref MP_TYPE_CODE_BASELINE_MP_PRIMARY_IMAGE (Baseline MP 主画像) を指定すると、Baseline MPフォーマットを使用します。
1530                     それ以外を指定すると、Extended MPフォーマットを使用します。<BR>
1531                     Baseline MPフォーマットではMP個別情報IFDを格納しませんので、以下の関数を呼んでも無効です。<BR>
1532                       @ref SetMpIndividualNum 、@ref SetMpPanOrientation 、@ref SetMpPanOverlapH 、@ref SetMpPanOverlapV 、
1533                       @ref SetMpBaseViewpointNum 、@ref SetMpConvergenceAngle 、@ref SetMpBaselineLength 、@ref SetMpVerticalDivergence 、
1534                       @ref SetMpAxisDistanceX 、@ref SetMpAxisDistanceY 、@ref SetMpAxisDistanceZ 、
1535                       @ref SetMpYawAngle 、@ref SetMpPitchAngle 、@ref SetMpRollAngle
1536 
1537         @param[out] dst                 エンコード結果を格納するバッファを指定します。<BR>
1538                                         指定した合計画像数のエンコードが完了するまで、このバッファを保持しておく必要があります。
1539                                         (エンコードを中止した場合は破棄できます)
1540 
1541         @param[in]  limit               dstのバイト数を指定します。
1542                                         このバイト数を超えるとエンコードに失敗します。<BR>
1543                                         指定した合計画像数のエンコード途中に @ref StartMpEncoderNext が失敗した場合、
1544                                         このバイト数が不足している可能性があります。
1545 
1546         @param[in]  src                 エンコードする画像データバッファを指定します。
1547                                         4バイトアラインメントが必要です。
1548 
1549         @param[in]  width               画像の横幅(pixel)を指定します。(65536未満)
1550 
1551         @param[in]  height              画像の縦幅(pixel)を指定します。(65536未満)
1552 
1553         @param[in]  quality             エンコードのクオリティを指定します。<BR>
1554                                         1~100 まで指定可能であり、100 に近づくほど高画質になりサイズが大きくなります。
1555 
1556         @param[in]  dstPixelSampling    画像の出力形式(画素サンプリング)を指定します。
1557 
1558         @param[in]  srcPixelFormat      エンコードする画像の入力ピクセルフォーマットを指定します。
1559 
1560         @param[in]  addThumbnail        サムネイルを付加するかどうかを指定します。
1561 
1562         @param[in]  numImages           1つのMPOに含む合計画像数を指定します。<BR>
1563                                         MP種別が立体視用画像の場合は、2以上にする必要があります。<BR>
1564                                         Baseline MP 主画像の場合は、3以下にする必要があります。<BR>
1565                                         デフォルトは2です。
1566 
1567         @param[in]  typeCode            MP種別を指定します。
1568                                         以下のいずれかの値を指定できます。<BR>
1569                                           @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) <BR>
1570                                           @ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像) <BR>
1571                                           @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) <BR>
1572                                           @ref MP_TYPE_CODE_UNDEFINED (未定義種別) <BR>
1573                                           @ref MP_TYPE_CODE_BASELINE_MP_PRIMARY_IMAGE (Baseline MP 主画像) <BR>
1574                                         デフォルトは @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) です。
1575 
1576         @param[in]  addImageUidList     個別画像ユニークIDリストを付加するかどうかを指定します。<BR>
1577                                         trueを指定すると付加し、falseを指定すると付加しません。<BR>
1578                                         付加する値は、本関数および @ref StartMpEncoderNext を呼ぶ直前に @ref SetImageUid で指定した画像ユニークIDです。<BR>
1579                                         @ref SetImageUid を呼ばなかった場合や、先頭画像の場合はNULL (全バイトが0)になります。<BR>
1580                                         デフォルトはfalseです。
1581 
1582         @param[in]  addTotalFrames      撮影時総コマ数を付加するかどうかを指定します。<BR>
1583                                         trueを指定すると付加し、falseを指定すると付加しません。<BR>
1584                                         MP種別(引数 typeCode)が @ref MP_TYPE_CODE_BASELINE_MP_PRIMARY_IMAGE の場合、指定は無視され、撮影時総コマ数を付加しません。<BR>
1585                                         付加する値は、通常は合計画像数になりますが、
1586                                         本関数および @ref StartMpEncoderNext を呼ぶ直前に @ref SetMpIndividualNum で個別画像番号を0に指定した場合、
1587                                         その画像はカウントされません。<BR>
1588                                         2枚目以降の、MP種別が @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_1 あるいは @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_2 (モニタ表示用画像)
1589                                         である画像もカウントされません。<BR>
1590                                         デフォルトはfalseです。
1591 
1592         @return     成功した場合、生成されたMPOのバイト数を返します。
1593                     (ただし合計画像数が1より大きい場合、このMPOは未完成状態です) <BR>
1594                     失敗した場合、0を返します。
1595                     失敗の原因は @ref GetLastError で取得できます。
1596      */
1597     size_t StartMpEncoderFirst(u8* dst,
1598                                size_t limit,
1599                                const void* src,
1600                                u32 width,
1601                                u32 height,
1602                                u32 quality,
1603                                PixelSampling dstPixelSampling,
1604                                PixelFormat srcPixelFormat,
1605                                bool addThumbnail,
1606                                u32 numImages = 2,
1607                                MpTypeCode typeCode = MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE,
1608                                bool addImageUidList = false,
1609                                bool addTotalFrames = false);
1610 
1611     /*!
1612         @brief      JPEGエンコードを実行し、直前の @ref StartMpEncoderFirst あるいは本関数によるエンコード結果に追記します。
1613 
1614                     それらの処理が失敗した場合は、本関数も失敗します。
1615                     (先頭画像からエンコードをやり直す必要があります)
1616 
1617                     本関数は、@ref StartMpEncoderFirst で指定した合計画像数が1より大きい場合、マルチピクチャオブジェクト(MPO)
1618                     を完成させるため、(合計画像数-1)回呼ぶ必要があります。
1619                     必要回数を超えて呼ぶと失敗します。
1620                     エンコード途中で失敗した場合や、エンコードを中止する場合は、それ以降本関数を呼ぶ必要はありません。
1621 
1622                     途中でエンコーダオブジェクトを初期化するとエンコード結果の追記ができませんので、
1623                     本関数を呼ぶ前に @ref Initialize を呼ばないでください。
1624 
1625                     本関数のエンコード結果は、@ref StartMpEncoderFirst で指定したバッファとバイト数の範囲内で、
1626                     直前の画像エンコード結果に追記します。
1627                     追記先のバイトオフセット(バッファ先頭から)が2の倍数になるようパディングされます。
1628                     このため、直前の個別画像のEOIマーカと、今回の個別画像のSOIマーカの間に1バイトの0が挿入される場合があります。
1629                     追記後にはパディングされません。
1630 
1631                     @ref SetUserMakerNote 、@ref SetMpTypeFlags 、@ref SetDateTime 等で登録した各種データや、
1632                     @ref SetThumbnailSize および @ref SetInputBufferWidth の指定は、
1633                     終了後、成功、失敗問わずクリアされます。
1634                     複数回エンコードする場合は、それぞれの画像エンコード前にそれらの関数を呼ぶ必要があります。
1635 
1636                     先頭画像のMP種別が @ref MP_TYPE_CODE_BASELINE_MP_PRIMARY_IMAGE (Baseline MP 主画像)の場合、Baseline MPフォーマットを使用しますので、
1637                     MP個別情報IFDを格納しません。@ref StartMpEncoderFirst と同様に、MP個別情報IFDを登録する関数を呼んでも無効です。
1638 
1639                     MP種別が @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_1 あるいは @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_2 (モニタ表示用画像)
1640                     の場合、APP1に記録するタグは以下のもののみとなります。
1641                     このため、モニタ表示用画像のエンコード直後に @ref GetMpRegionsToBuildJpegData を使ってJPEGデータの再構成はできません。
1642                       IFD0 の Exif IFD Pointer、
1643                       Exif Private Tag の MakerNote (メーカーノート登録時)、PixelXDimension (*)、PixelYDimension (*)、ImageUniqueID (画像ユニークID登録時)、
1644                       IFD1 の JPEGInterchangeFormat (サムネイル付加時)、JPEGInterchangeFormatLength (サムネイル付加時)。
1645                     (*) MPフォーマット規格では、これらのタグは「モニタ元画像と同じ場合、記録しないことを推奨する」となっています。
1646                         エンコードする画像サイズ(引数 width および height)が、モニタ元画像の画像サイズと同じかどうかはアプリケーションで確認してください。
1647                         引数 omitPixelDimensions にtrueを指定すると、記録しません。
1648 
1649         @param[in]  src                 エンコードする画像データバッファを指定します。
1650                                         4バイトアラインメントが必要です。
1651 
1652         @param[in]  width               画像の横幅(pixel)を指定します。(65536未満)
1653 
1654         @param[in]  height              画像の縦幅(pixel)を指定します。(65536未満)
1655 
1656         @param[in]  quality             エンコードのクオリティを指定します。<BR>
1657                                         1~100 まで指定可能であり、100 に近づくほど高画質になりサイズが大きくなります。
1658 
1659         @param[in]  dstPixelSampling    画像の出力形式(画素サンプリング)を指定します。
1660 
1661         @param[in]  srcPixelFormat      エンコードする画像の入力ピクセルフォーマットを指定します。
1662 
1663         @param[in]  addThumbnail        サムネイルを付加するかどうかを指定します。
1664 
1665         @param[in]  typeCode            MP種別を指定します。
1666                                         以下のいずれかの値を指定できます。<BR>
1667                                           @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) <BR>
1668                                           @ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像) <BR>
1669                                           @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) <BR>
1670                                           @ref MP_TYPE_CODE_UNDEFINED (未定義種別) <BR>
1671                                           @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_1 および @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_2 (モニタ表示用画像) <BR>
1672                                         なお、モニタ表示用画像以外を指定する場合、先頭画像のMP種別と同じである必要があります。<BR>
1673                                         デフォルトは @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) です。
1674 
1675         @param[in]  omitPixelDimensions MP種別(引数 typeCode)が @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_1 あるいは @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_2 (モニタ表示用画像)
1676                                         の場合、APP1へ実効画像サイズ(PixelXDimension、PixelYDimension)の記録を省略するかどうかを指定します。<BR>
1677                                         それ以外のMP種別では記録は省略できないため、指定は無視されます。<BR>
1678                                         trueを指定すると省略し、falseを指定すると記録します。<BR>
1679                                         デフォルトはfalseです。
1680 
1681         @return     成功した場合、生成されたMPOのバイト数を返します。
1682                     (ただし必要回数の呼び出しが成功するまでは、このMPOは未完成状態です) <BR>
1683                     失敗した場合、0を返します。
1684                     失敗の原因は @ref GetLastError で取得できます。
1685      */
1686     size_t StartMpEncoderNext(const void* src,
1687                               u32 width,
1688                               u32 height,
1689                               u32 quality,
1690                               PixelSampling dstPixelSampling,
1691                               PixelFormat srcPixelFormat,
1692                               bool addThumbnail,
1693                               MpTypeCode typeCode = MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE,
1694                               bool omitPixelDimensions = false);
1695 
1696     /*!
1697         @brief      直前の @ref StartMpEncoderFirst 、@ref StartMpEncoderNext あるいは @ref StartMpEncoderLR によるエンコード結果から、
1698                     JPEGデータを再構成するための領域情報を取得します。
1699 
1700                     それらの処理が失敗した場合は、本関数も失敗します。
1701                     直前に @ref StartJpegEncoder を呼んだ場合も失敗します。
1702                     直前に @ref StartMpEncoderNext でモニタ表示用画像をエンコードした場合も失敗します。
1703                     JPEGデータの再構成にはエンコード結果が必要です。破棄しないでください。
1704 
1705                     本関数は、同じ画像をMPフォーマットと、MPフォーマットではないJPEG形式で繰り返しエンコードする代わりに、
1706                     前者の結果を利用して高速に後者の結果を得るために使います。
1707 
1708                     MPフォーマットの個別画像データ構造は、簡単には「(JPEGヘッダ) + (APP2) + (JPEGデータ)」のようになっており、
1709                     APP2はMPフォーマット付属情報を含んでいます。
1710                     APP2を切り詰めれば、「(JPEGヘッダ) + (JPEGデータ)」となり、MPフォーマットではないJPEG形式でエンコードした結果と一致します。
1711                     本関数は、「(JPEGヘッダ)」と「(JPEGデータ)」の領域情報(ポインタとバイト数)を取得します。
1712 
1713                     直前に @ref StartMpEncoderLR を呼んだ場合、取得できるのは左目用画像の領域情報になります。
1714 
1715         @param[out] pBuffer             領域情報を格納するバッファです。
1716 
1717         @return     成功した場合、trueを返します。
1718                     失敗した場合、falseを返します。<BR>
1719                     失敗の原因は取得できません。本関数は @ref GetLastError が返す値を更新しません。
1720      */
1721     bool GetMpRegionsToBuildJpegData(MpRegionsToBuildJpegData* pBuffer);
1722 
1723     /*!
1724         @brief      直前の @ref StartMpEncoderFirst 、@ref StartMpEncoderNext あるいは @ref StartMpEncoderLR によるエンコードの失敗原因を取得します。
1725 
1726         @return     直前のエンコードが成功した場合、@ref JPEG_ENCODER_ERROR_NONE (0) を返します。<BR>
1727                     エンコーダオブジェクトの初期化直後および再初期化直後も0を返します。<BR>
1728                     失敗した場合、0以外の値を返します。リファレンスは追って作成します。
1729      */
1730     s32 GetLastError() const;
1731 
1732     /*!
1733         @brief      エンコーダオブジェクトの終了処理を行います。
1734 
1735         @return     なし。
1736      */
Finalize()1737     void Finalize() { m_Initialized = false; }
1738 
1739     /*!
1740         @brief      デストラクタです。
1741                     内部で Finalize() を呼びます。
1742      */
~JpegMpEncoder()1743     ~JpegMpEncoder() { Finalize(); }
1744 
1745 
1746 protected:
1747     detail::JpegMpEncoderWorkObj* m_pWork;
1748     bool    m_Initialized;
1749     bool    m_Padding[3];
1750 
1751     detail::JpegMpEncoderTemporarySettingObj m_TemporarySetting;
1752     void ClearTemporarySetting();
1753 
1754     void SetMakerNote(const u8* pBuffer, size_t size, u32 index);
1755 };
1756 
1757 } // namespace CTR {
1758 } // namespace jpeg {
1759 } // namespace nn {
1760 
1761 #endif // __cplusplus
1762 
1763 #endif // NN_JPEG_JPEGMPENCODER_H_
1764