/*---------------------------------------------------------------------------* Project: Horizon File: jpeg_MpEncoder.h Copyright (C)2009-2010 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 26510 $ *---------------------------------------------------------------------------*/ /*! @file @brief JpegMpEncoder に関するAPIの宣言 :include nn/jpeg.h */ #ifndef NN_JPEG_JPEGMPENCODER_H_ #define NN_JPEG_JPEGMPENCODER_H_ #include #include #include #ifdef __cplusplus namespace nn { namespace jpeg { namespace CTR { namespace detail { struct JpegMpEncoderWorkObj; } /*! @brief JPEGエンコードを行うクラスです。 */ class JpegMpEncoder : private nn::util::NonCopyable { public: /*! @brief エンコーダオブジェクト用ワークバッファのバイト数を計算します。 バッファの確保と解放はアプリケーションで行ってください。 @param[in] numImages MP(マルチピクチャ)フォーマットを使用せず、通常のJPEGフォーマットのみを使用する場合は0を指定します。
MPフォーマットを使用する場合は、格納する画像数を指定します。
MPフォーマットを使用するかどうか、あるいは格納する画像数が未定のままバッファを確保する必要がある場合、 アプリケーションが想定する最大格納画像数を指定してください。
デフォルトは0です。 @return バッファのバイト数を返します。 ただし、格納する画像数(numImages)が大きすぎる(4096以上)場合には、エラーとして0を返します。 */ static size_t GetWorkBufferSize(u32 numImages = 0); /*! @brief エンコーダオブジェクトを構築します。 初期化しません。 */ JpegMpEncoder() : m_Initialized(false) {} /*! @brief エンコーダオブジェクトを初期化します。 エンコーダオブジェクト用ワークバッファも初期化します。 初期化を一度行えば、MPフォーマットへ格納する画像数に変更がない限り、終了するまで再初期化不要です。 @ref StartMpEncoderNext を呼ぶ前でなければ、再初期化してもかまいません。 @param[out] workBuffer エンコーダオブジェクト用ワークバッファを指定します。 4バイトアラインメントが必要です。
バッファサイズは @ref GetWorkBufferSize で計算します。
ワークバッファはエンコーダオブジェクト毎に必要です。 @param[in] workBufferSize バッファのバイト数を指定します。 @ref GetWorkBufferSize の返り値を指定してください。 @param[in] numImages MPフォーマットへ格納する画像数を指定します。
@ref GetWorkBufferSize 呼び出し時と同じかそれ以下の値を指定してください。
デフォルトは0です。 @return 成功した場合、trueを返します。 失敗した場合、falseを返します。 workBufferのアラインメントと、他の引数を確認してください。 */ bool Initialize(void* workBuffer, size_t workBufferSize, u32 numImages = 0); /*! @brief サムネイルの画像サイズおよび出力形式を指定します。 エンコード関数がサムネイルを付加する場合、 サムネイルの画像サイズ(pixel)は、デフォルトでは横幅 @ref DEFAULT_THUMBNAIL_WIDTH (160)、 縦幅 @ref DEFAULT_THUMBNAIL_HEIGHT (120) となり、アスペクト比は4:3です。 サムネイルは指定された画像サイズで生成されるため、元画像のアスペクト比が4:3でない場合、 縮小率が縦方向と横方向で異なる、歪んだサムネイルが生成されます。 本関数でサムネイル画像サイズを指定することにより、元画像とサムネイルのアスペクト比を一致あるいは近づけることができます。 サムネイル画像サイズを大きくしすぎると、APP1セグメント(0xFFFFバイトまで)に収まらず、エンコードが失敗する可能性があります。 指定できる画像サイズは、出力形式(引数 dstPixelSampling)によって変わります。
@ref PIXEL_SAMPLING_YUV444 を指定した場合は、縦横サイズがそれぞれ8の倍数である必要があります。
@ref PIXEL_SAMPLING_YUV420 を指定した場合は、縦横サイズがそれぞれ16の倍数である必要があります。
@ref PIXEL_SAMPLING_YUV422 を指定した場合は、縦サイズが8の倍数、横サイズが16の倍数である必要があります。 デフォルトの画像出力形式は @ref DEFAULT_THUMBNAIL_PIXEL_SAMPLING ( @ref PIXEL_SAMPLING_YUV422 ) です。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 引数 width、height、dstPixelSamplingの組み合わせが不正な場合は、 全てデフォルト値で置き換えられます。 @param[in] width サムネイルの横幅(pixel)を指定します。(65536未満) @param[in] height サムネイルの縦幅(pixel)を指定します。(65536未満) @param[in] dstPixelSampling 画像の出力形式(画素サンプリング)を指定します。
デフォルトは @ref DEFAULT_THUMBNAIL_PIXEL_SAMPLING ( @ref PIXEL_SAMPLING_YUV422 ) です。 @return なし。 */ void SetThumbnailSize(u32 width, u32 height, PixelSampling dstPixelSampling = DEFAULT_THUMBNAIL_PIXEL_SAMPLING) { if (m_Initialized) { m_TemporarySetting.thumbnailWidth = width; m_TemporarySetting.thumbnailHeight = height; m_TemporarySetting.thumbnailSampling = dstPixelSampling; } } /*! @brief 入力画像バッファの横幅を指定します。 本関数は、エンコードしたい画像横幅より、その画像バッファ(例えばGPUテクスチャバッファ) の画像横幅が大きい場合に使います。 入力画像バッファの画像横幅を指定することにより、 エンコード関数が入力画像バッファから左詰めで切り抜き処理を行います。 サムネイルを付加する場合、主画像と同様に切り抜き後の画像から縮小処理を行います。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 width に0を指定するか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 本関数で指定した画像横幅より、エンコード関数で指定したものが大きい場合は、 エンコード関数の指定が優先されます。 引数 width は、エンコード関数で指定する入力ピクセルフォーマットに応じて以下の制限があります。 (エンコード時にそれぞれの倍数へ切り下げられます)
@ref PIXEL_FORMAT_YUYV8 の場合、2の倍数である必要があります。
@ref PIXEL_FORMAT_CTR_RGB565_BLOCK8 、@ref PIXEL_FORMAT_CTR_RGB8_BLOCK8 、あるいは @ref PIXEL_FORMAT_CTR_RGBA8_BLOCK8 の場合、8の倍数である必要があります。 @param[in] width 入力画像バッファの横幅(pixel)を指定します。
0を指定すると、エンコード関数での指定が優先されます。
MAX_ENCODER_INPUT_BUFFER_WIDTH (65536) を超える値の指定は無視されます。 @return なし。 */ void SetInputBufferWidth(u32 width) { if (m_Initialized) { if (width <= MAX_ENCODER_INPUT_BUFFER_WIDTH) { m_TemporarySetting.inputBufferWidth = width; } } } /*! @brief JPEGに埋め込む撮影日時情報を登録します。 この情報は、IFD0 の DateTime と、ExifIFD の DateTimeOriginal タグ、DateTimeDigitized タグとして登録されます。 デフォルトは未登録で、この場合はエンコード関数が内部で @ref GetDateTimeNow を呼び、現在時刻を登録します。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pBuffer にNULLを指定するか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pBuffer 日時情報を指定します。 文字列は「YYYY:MM:DD HH:MM:DD」+0x00 の 20 文字としてください。
NULLを指定するとクリアします。 @return なし。 */ void SetDateTime(const char* pBuffer) { if (m_Initialized) { if (pBuffer) { memcpy(m_TemporarySetting.dateTimeBuffer, pBuffer, sizeof(m_TemporarySetting.dateTimeBuffer)); m_TemporarySetting.dateTimeBuffer[sizeof(m_TemporarySetting.dateTimeBuffer) - 1] = '\0'; m_TemporarySetting.isDateTimeSet = true; } else { m_TemporarySetting.isDateTimeSet = false; } } } /*! @brief 現在日時を取得し、@ref SetDateTime の引数に指定できる文字列を作成します。 現在日時の取得には @ref nn::fnd::DateTime::GetNow を使っています。 @param[out] pBuffer 日時情報を格納するバッファを指定します。 バッファのバイト数は @ref DATE_TIME_SIZE (20) です。 @return なし。 */ static void GetDateTimeNow(char* pBuffer); /*! @brief JPEGのExif IFDに埋め込む、ソフトウェア名を登録します。 この情報は、IFD0 の Software タグとして登録されます。 デフォルトは未登録です。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pBuffer にNULLを指定するか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pBuffer ソフトウェア名を指定します。 @return なし。 */ void SetSoftware(const char* pBuffer) { if (m_Initialized) { m_TemporarySetting.pSoftware = pBuffer; } } /*! @brief JPEGのメーカーノート部分に埋め込む各種データを登録します。 埋め込まれたデータを取得するためには、デコードあるいはExif情報の抽出を行った後、 @ref JpegMpDecoder::GetLastUserMakerNotePointer および @ref JpegMpDecoder::GetLastUserMakerNoteSize を呼んでください。 ・登録できる最大サイズについて
メーカーノートに登録できるデータのサイズは、APP1セグメント全体のサイズに依存します。 メーカーノートはExifに含まれるため、APP1セグメントの一部となりますが、このAPP1セグメントは0xFFFFまでのサイズしか扱えないようになっています。 そのため、サムネイル等のAPP1領域のデータサイズによって、メーカーノートに埋め込めるデータのサイズは変動することになります。 (目安として 640x480の画像をサムネイル付き、YUV422、クオリティ90でエンコードする場合、トータル 0xE000 以下までのサイズにすることをお勧めします。) 本関数は、エンコード関数を呼ぶ前に呼んでください。 埋め込むデータはエンコード関数終了まで破棄しないでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pBuffer にNULLを指定するか、size に0を指定するか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pBuffer 埋め込むデータを指定します。 NULLを指定するとクリアします。 @param[in] size 埋め込むデータのバイト数を指定します。 0を指定するとクリアします。 @return なし。 */ void SetUserMakerNote(const u8* pBuffer, size_t size); /*! @brief JPEGのExif IFDに埋め込む、画像ユニークIDを登録します。 埋め込まれたデータを取得するためには、デコードあるいはExif情報の抽出を行った後、 @ref JpegMpDecoder::GetLastImageUid を呼んでください。 MPフォーマットを使用する場合、@ref StartMpEncoderFirst で「個別画像ユニークIDリストを付加する」と指定すると、 @ref StartMpEncoderNext 呼び出し毎に、本関数で登録したIDが個別画像ユニークIDとしてコピーされます。 (先頭画像を除く) 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pBuffer にNULLを指定するか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pBuffer 画像ユニークIDを指定します。
文字列は128ビットの整数値を16進数表記したASCII文字列(32文字)で、バイト数は末尾の '\0' を含み @ref IMAGE_UID_SIZE (33) バイトです。
NULLを指定するとクリアします。 @return なし。 */ void SetImageUid(const char* pBuffer) { if (m_Initialized) { if (pBuffer) { memcpy(m_TemporarySetting.imageUidBuffer, pBuffer, sizeof(m_TemporarySetting.imageUidBuffer)); m_TemporarySetting.imageUidBuffer[sizeof(m_TemporarySetting.imageUidBuffer) - 1] = '\0'; m_TemporarySetting.isImageUidSet = true; } else { m_TemporarySetting.isImageUidSet = false; } } } /*! @brief JPEGのExif IFDに埋め込む、画像方向を登録します。 この情報は、IFD0 の Orientation タグとして登録されます。 デフォルトは未登録です。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、@ref ClearOrientation を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] orientation 画像方向(1から8まで)を指定します。 @return なし。 */ void SetOrientation(u16 orientation) { if (m_Initialized) { m_TemporarySetting.orientation = orientation; m_TemporarySetting.isOrientationSet = true; } } /*! @brief JPEGのExif IFDに画像方向を埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearOrientation() { if (m_Initialized) { m_TemporarySetting.isOrientationSet = false; } } // リファレンスは追って作成します。 // GPS情報のエンコードは、GpsData構造体を初期化して、登録したい情報をSetGps*()で構造体へ設定します。 // 最後に、構造体を @ref SetGpsData で登録します。 static void InitializeGpsData(GpsData* pGps) { memset(pGps, 0, sizeof(*pGps)); // GPSタグのバージョン 2.2。 pGps->versionId[0] = 2; pGps->versionId[1] = 2; pGps->isVersionIdValid = true; } // 本関数は、エンコード関数を呼ぶ前に呼んでください。 // 埋め込むデータはエンコード関数終了まで破棄しないでください。 // エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 // 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 // 他にも、引数 pGps にNULLを指定するか、@ref ClearGpsData を呼ぶか、 // @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 // @ref StartMpEncoderLR では両方の画像に登録されます。 void SetGpsData(const GpsData* pGps) { if (m_Initialized) { m_TemporarySetting.pGpsData = pGps; } } // JPEGにGPS情報を埋め込まないよう指示します。(デフォルト動作) void ClearGpsData() { SetGpsData(NULL); } static void SetGpsVersionId(GpsData* pGps, const u8* pVersionId) { NN_ASSERT(pGps); if (pVersionId) { memcpy(pGps->versionId, pVersionId, sizeof(pGps->versionId)); pGps->isVersionIdValid = true; } else { pGps->isVersionIdValid = false; } } static void ClearGpsVersionId(GpsData* pGps) { SetGpsVersionId(pGps, NULL); } static void SetGpsLatitude(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->latitudeRef[0] = ref; pGps->latitudeRef[1] = '\0'; if (pValue) { memcpy(pGps->latitude, pValue, sizeof(pGps->latitude)); pGps->isLatitudeValid = true; } else { pGps->isLatitudeValid = false; } } static void ClearGpsLatitude(GpsData* pGps) { SetGpsLatitude(pGps, '\0', NULL); } static void SetGpsLongitude(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->longitudeRef[0] = ref; pGps->longitudeRef[1] = '\0'; if (pValue) { memcpy(pGps->longitude, pValue, sizeof(pGps->longitude)); pGps->isLongitudeValid = true; } else { pGps->isLongitudeValid = false; } } static void ClearGpsLongitude(GpsData* pGps) { SetGpsLongitude(pGps, '\0', NULL); } static void SetGpsAltitude(GpsData* pGps, u8 ref, const Rational* pValue) { NN_ASSERT(pGps); if (pValue) { pGps->altitudeRef = ref; memcpy(&pGps->altitude, pValue, sizeof(pGps->altitude)); pGps->isAltitudeRefValid = pGps->isAltitudeValid = true; } else { pGps->isAltitudeRefValid = pGps->isAltitudeValid = false; } } static void ClearGpsAltitude(GpsData* pGps) { SetGpsAltitude(pGps, 0, NULL); } static void SetGpsTimeStamp(GpsData* pGps, const Rational* pValue) { NN_ASSERT(pGps); if (pValue) { memcpy(pGps->timeStamp, pValue, sizeof(pGps->timeStamp)); pGps->isTimeStampValid = true; } else { pGps->isTimeStampValid = false; } } static void ClearGpsTimeStamp(GpsData* pGps) { SetGpsTimeStamp(pGps, NULL); } static void SetGpsSatellites(GpsData* pGps, const char* pSatellites) { NN_ASSERT(pGps); pGps->pSatellites = pSatellites; } static void ClearGpsSatellites(GpsData* pGps) { SetGpsSatellites(pGps, NULL); } static void SetGpsStatus(GpsData* pGps, char status) { NN_ASSERT(pGps); pGps->status[0] = status; pGps->status[1] = '\0'; } static void ClearGpsStatus(GpsData* pGps) { SetGpsStatus(pGps, '\0'); } static void SetGpsMeasureMode(GpsData* pGps, char measureMode) { NN_ASSERT(pGps); pGps->measureMode[0] = measureMode; pGps->measureMode[1] = '\0'; } static void ClearGpsMeasureMode(GpsData* pGps) { SetGpsMeasureMode(pGps, '\0'); } static void SetGpsDop(GpsData* pGps, const Rational* pValue) { NN_ASSERT(pGps); if (pValue) { memcpy(&pGps->dop, pValue, sizeof(pGps->dop)); pGps->isDopValid = true; } else { pGps->isDopValid = false; } } static void ClearGpsDop(GpsData* pGps) { SetGpsDop(pGps, NULL); } static void SetGpsSpeed(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->speedRef[0] = ref; pGps->speedRef[1] = '\0'; if (pValue) { memcpy(&pGps->speed, pValue, sizeof(pGps->speed)); pGps->isSpeedValid = true; } else { pGps->isSpeedValid = false; } } static void ClearGpsSpeed(GpsData* pGps) { SetGpsSpeed(pGps, '\0', NULL); } static void SetGpsTrack(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->trackRef[0] = ref; pGps->trackRef[1] = '\0'; if (pValue) { memcpy(&pGps->track, pValue, sizeof(pGps->track)); pGps->isTrackValid = true; } else { pGps->isTrackValid = false; } } static void ClearGpsTrack(GpsData* pGps) { SetGpsTrack(pGps, '\0', NULL); } static void SetGpsImgDirection(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->imgDirectionRef[0] = ref; pGps->imgDirectionRef[1] = '\0'; if (pValue) { memcpy(&pGps->imgDirection, pValue, sizeof(pGps->imgDirection)); pGps->isImgDirectionValid = true; } else { pGps->isImgDirectionValid = false; } } static void ClearGpsImgDirection(GpsData* pGps) { SetGpsImgDirection(pGps, '\0', NULL); } static void SetGpsMapDatum(GpsData* pGps, const char* pMapDatum) { NN_ASSERT(pGps); pGps->pMapDatum = pMapDatum; } static void ClearGpsMapDatum(GpsData* pGps) { SetGpsMapDatum(pGps, NULL); } static void SetGpsDestLatitude(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->destLatitudeRef[0] = ref; pGps->destLatitudeRef[1] = '\0'; if (pValue) { memcpy(pGps->destLatitude, pValue, sizeof(pGps->destLatitude)); pGps->isDestLatitudeValid = true; } else { pGps->isDestLatitudeValid = false; } } static void ClearGpsDestLatitude(GpsData* pGps) { SetGpsDestLatitude(pGps, '\0', NULL); } static void SetGpsDestLongitude(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->destLongitudeRef[0] = ref; pGps->destLongitudeRef[1] = '\0'; if (pValue) { memcpy(pGps->destLongitude, pValue, sizeof(pGps->destLongitude)); pGps->isDestLongitudeValid = true; } else { pGps->isDestLongitudeValid = false; } } static void ClearGpsDestLongitude(GpsData* pGps) { SetGpsDestLongitude(pGps, '\0', NULL); } static void SetGpsDestBearing(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->destBearingRef[0] = ref; pGps->destBearingRef[1] = '\0'; if (pValue) { memcpy(&pGps->destBearing, pValue, sizeof(pGps->destBearing)); pGps->isDestBearingValid = true; } else { pGps->isDestBearingValid = false; } } static void ClearGpsDestBearing(GpsData* pGps) { SetGpsDestBearing(pGps, '\0', NULL); } static void SetGpsDestDistance(GpsData* pGps, char ref, const Rational* pValue) { NN_ASSERT(pGps); pGps->destDistanceRef[0] = ref; pGps->destDistanceRef[1] = '\0'; if (pValue) { memcpy(&pGps->destDistance, pValue, sizeof(pGps->destDistance)); pGps->isDestDistanceValid = true; } else { pGps->isDestDistanceValid = false; } } static void ClearGpsDestDistance(GpsData* pGps) { SetGpsDestDistance(pGps, '\0', NULL); } static void SetGpsProcessingMethod(GpsData* pGps, const u8* pProcessingMethod, size_t processingMethodSize) { NN_ASSERT(pGps); if (pProcessingMethod && processingMethodSize) { pGps->pProcessingMethod = pProcessingMethod; pGps->processingMethodSize = processingMethodSize; } else { pGps->pProcessingMethod = NULL; pGps->processingMethodSize = 0; } } static void ClearGpsProcessingMethod(GpsData* pGps) { SetGpsProcessingMethod(pGps, NULL, 0); } static void SetGpsAreaInformation(GpsData* pGps, const u8* pAreaInformation, size_t areaInformationSize) { NN_ASSERT(pGps); if (pAreaInformation && areaInformationSize) { pGps->pAreaInformation = pAreaInformation; pGps->areaInformationSize = areaInformationSize; } else { pGps->pAreaInformation = NULL; pGps->areaInformationSize = 0; } } static void ClearGpsAreaInformation(GpsData* pGps) { SetGpsAreaInformation(pGps, NULL, 0); } static void SetGpsDateStamp(GpsData* pGps, const char* pDateStamp) { NN_ASSERT(pGps); pGps->pDateStamp = pDateStamp; } static void ClearGpsDateStamp(GpsData* pGps) { SetGpsDateStamp(pGps, NULL); } static void SetGpsDifferential(GpsData* pGps, u16 differential) { NN_ASSERT(pGps); pGps->differential = differential; pGps->isDifferentialValid = true; } static void ClearGpsDifferential(GpsData* pGps) { NN_ASSERT(pGps); pGps->isDifferentialValid = false; } /*! @brief JPEGエンコードを実行します。 本関数でエンコードできる画像の縦横サイズは画像の出力形式(引数 dstPixelSampling)によって変わります。
@ref PIXEL_SAMPLING_YUV444 を指定した場合は、縦横サイズがそれぞれ8の倍数である必要があります。
@ref PIXEL_SAMPLING_YUV420 を指定した場合は、縦横サイズがそれぞれ16の倍数である必要があります。
@ref PIXEL_SAMPLING_YUV422 を指定した場合は、縦サイズが8の倍数、横サイズが16の倍数である必要があります。 @param[out] dst エンコード結果を格納するバッファを指定します。 @param[in] limit dstのバイト数を指定します。 このバイト数を超えるとエンコードに失敗します。 @param[in] src エンコードする画像データバッファを指定します。 4バイトアラインメントが必要です。 @param[in] width 画像の横幅(pixel)を指定します。(65536未満) @param[in] height 画像の縦幅(pixel)を指定します。(65536未満) @param[in] quality エンコードのクオリティを指定します。
1~100 まで指定可能であり、100 に近づくほど高画質になりサイズが大きくなります。 @param[in] dstPixelSampling 画像の出力形式(画素サンプリング)を指定します。 @param[in] srcPixelFormat エンコードする画像の入力ピクセルフォーマットを指定します。 @param[in] addThumbnail サムネイルを付加するかどうかを指定します。 @return 成功した場合、生成されたJPEGフォーマットデータのバイト数を返します。 失敗した場合、0を返します。
失敗の原因は @ref GetLastError で取得できます。 */ size_t StartJpegEncoder(u8* dst, size_t limit, const void* src, u32 width, u32 height, u32 quality, PixelSampling dstPixelSampling, PixelFormat srcPixelFormat, bool addThumbnail); /*! @brief JPEGエンコードを2枚の画像に対して実行し、Extended MPフォーマット(立体視用)で格納します。 最初に左目用画像をエンコードし、MPフォーマットの先頭画像(かつ代表画像)として格納します。 成功すれば、続けて右目用画像をエンコードし格納します。 本関数では、左目用画像の視点番号は1、基準視点番号も1です。 右目用画像の視点番号は2です。 本関数でエンコードできる画像の縦横サイズは画像の出力形式(引数 dstPixelSampling)によって変わります。 @ref StartJpegEncoder と同じです。 輻輳角および基線長はデフォルト値 {0xFFFFFFFF,0xFFFFFFFF} になります。 以下の各種データ登録関数を呼んでも効果がありません。
@ref SetUserMakerNote 、@ref SetImageUid 、 @ref SetMpTypeFlags 、@ref SetMpIndividualNum 、 @ref SetMpPanOrientation 、@ref SetMpPanOverlapH 、@ref SetMpPanOverlapV 、 @ref SetMpBaseViewpointNum 、@ref SetMpConvergenceAngle 、@ref SetMpBaselineLength 、@ref SetMpVerticalDivergence 、 @ref SetMpAxisDistanceX 、@ref SetMpAxisDistanceY 、@ref SetMpAxisDistanceZ 、 @ref SetMpYawAngle 、@ref SetMpPitchAngle 、@ref SetMpRollAngle 以下の関数を呼んだ場合、指定は両方の画像に対して有効で、同一値が登録されます。 (@ref SetDateTime を呼ばなかった場合は先頭画像のエンコード時に現在日時を取得し、2枚の画像の日時情報は同じになります。)
@ref SetThumbnailSize 、@ref SetInputBufferWidth 、@ref SetDateTime 、@ref SetSoftware 、 @ref SetOrientation 、@ref SetGpsData @param[out] dst エンコード結果を格納するバッファを指定します。 @param[in] limit dstのバイト数を指定します。 このバイト数を超えるとエンコードに失敗します。 @param[in] srcL エンコードする左目用画像データバッファを指定します。 4バイトアラインメントが必要です。 @param[in] srcR エンコードする右目用画像データバッファを指定します。 4バイトアラインメントが必要です。 @param[in] width 画像の横幅(pixel)を指定します。(65536未満) サムネイル以外の左右画像で共通です。 @param[in] height 画像の縦幅(pixel)を指定します。(65536未満) サムネイル以外の左右画像で共通です。 @param[in] quality エンコードのクオリティを指定します。
1~100 まで指定可能であり、100 に近づくほど高画質になりサイズが大きくなります。
サムネイル以外の左右画像で共通です。 @param[in] dstPixelSampling 画像の出力形式(画素サンプリング)を指定します。 サムネイル以外の左右画像で共通です。 @param[in] srcPixelFormat エンコードする画像の入力ピクセルフォーマットを指定します。 全ての画像で共通です。 @param[in] addThumbnailL 左目用画像へサムネイルを付加するかどうかを指定します。 @param[in] addThumbnailR 右目用画像へサムネイルを付加するかどうかを指定します。 @return 成功した場合、生成されたMPフォーマットデータのバイト数を返します。 失敗した場合、0を返します。
失敗の原因は @ref GetLastError で取得できます。 */ size_t StartMpEncoderLR(u8* dst, size_t limit, const void* srcL, const void* srcR, u32 width, u32 height, u32 quality, PixelSampling dstPixelSampling, PixelFormat srcPixelFormat, bool addThumbnailL, bool addThumbnailR); /*! @brief MPエントリに埋め込む、個別画像種別管理情報の各種フラグと、従属画像エントリ番号を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます) 個別画像種別管理情報のフィールドのうち、「従属親画像フラグ」、「従属子画像フラグ」、「代表画像フラグ」 を指定できます。 他のフィールドのうち、「予約(0)」、「データ形式(0: JPEG)」はライブラリで固定されており、指定できません。 「種別コード」は @ref StartMpEncoderFirst で指定します。 本関数を呼ばずに @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使っても問題ありません。 デフォルトで、「従属親画像フラグ=0」、「従属子画像フラグ=0」、 「代表画像フラグ=先頭画像のみ1、他は0」となります。 デフォルト動作の詳細は以下の通りです。
1. 本関数を呼ばずに @ref StartMpEncoderFirst を使った場合、 この画像(先頭画像)が代表画像(代表画像フラグ=1)となります。
2. 本関数を呼ばずに @ref StartMpEncoderNext を使った場合、 まだ代表画像が存在していなければ、この画像が代表画像となります。 代表画像が存在していれば、この画像は代表画像フラグ=0となります。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] flags @ref MpTypeFlag を単独あるいは論理和で指定します。0も指定できます。
@ref MP_TYPE_FLAG_REPRESENTATIVE_IMAGE (代表画像フラグ)をセットしても、 既に代表画像が存在していれば無視されます。
デフォルトは0です。 @param[in] image1 従属画像1エントリ番号を指定します。 デフォルトは0です。 @param[in] image2 従属画像2エントリ番号を指定します。 デフォルトは0です。 @return なし。 */ void SetMpTypeFlags(u32 flags = 0, u16 image1 = 0, u16 image2 = 0) { if (m_Initialized) { m_TemporarySetting.isDependentParent = (flags & MP_TYPE_FLAG_DEPENDENT_IMAGE_PARENT) ? true : false; m_TemporarySetting.isDependentChild = (flags & MP_TYPE_FLAG_DEPENDENT_IMAGE_CHILD) ? true : false; m_TemporarySetting.isRepresentativeSet = true; m_TemporarySetting.isRepresentative = (flags & MP_TYPE_FLAG_REPRESENTATIVE_IMAGE) ? true : false; m_TemporarySetting.dependentImage1EntryNum = image1; m_TemporarySetting.dependentImage2EntryNum = image2; } } /*! @brief MP個別情報IFDに埋め込む、個別画像番号を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます) 本関数を呼ばない場合、ライブラリがデフォルト値を登録します。 デフォルト値は @ref StartMpEncoderFirst を呼ぶと1に初期化され、エンコード関数終了後、1ずつ増加します。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、@ref ClearMpIndividualNum を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] value 個別画像番号を指定します。 @return なし。 */ void SetMpIndividualNum(u32 value) { if (m_Initialized) { m_TemporarySetting.mpAttribute.mpIndividualNum = value; m_TemporarySetting.mpAttribute.isMpIndividualNumValid = true; } } /*! @brief MP個別情報IFDに埋め込む、個別画像番号をデフォルト値に戻します。 @return なし。 */ void ClearMpIndividualNum() { if (m_Initialized) { m_TemporarySetting.mpAttribute.isMpIndividualNumValid = false; } } /*! @brief MP個別情報IFDに埋め込む、画像配置を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、@ref ClearMpPanOrientation を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] value 画像配置を指定します。 @return なし。 */ void SetMpPanOrientation(u32 value) { if (m_Initialized) { m_TemporarySetting.mpAttribute.panOrientation = value; m_TemporarySetting.mpAttribute.isPanOrientationValid = true; } } /*! @brief MP個別情報IFDに画像配置を埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpPanOrientation() { if (m_Initialized) { m_TemporarySetting.mpAttribute.isPanOrientationValid = false; } } /*! @brief MP個別情報IFDに埋め込む、水平オーバーラップを登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpPanOverlapH を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue 水平オーバーラップを指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpPanOverlapH(const Rational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.panOverlapH = *pValue; m_TemporarySetting.mpAttribute.isPanOverlapHValid = true; } else { m_TemporarySetting.mpAttribute.isPanOverlapHValid = false; } } } /*! @brief MP個別情報IFDに水平オーバーラップを埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpPanOverlapH() { SetMpPanOverlapH(NULL); } /*! @brief MP個別情報IFDに埋め込む、垂直オーバーラップを登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpPanOverlapV を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue 垂直オーバーラップを指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpPanOverlapV(const Rational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.panOverlapV = *pValue; m_TemporarySetting.mpAttribute.isPanOverlapVValid = true; } else { m_TemporarySetting.mpAttribute.isPanOverlapVValid = false; } } } /*! @brief MP個別情報IFDに垂直オーバーラップを埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpPanOverlapV() { SetMpPanOverlapV(NULL); } /*! @brief MP個別情報IFDに埋め込む、基準視点番号を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます) 本関数を呼ばない場合、ライブラリがデフォルト値(1)を登録します。 ただし、画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) でも @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) でもない場合、 値は埋め込まれません。 基準視点番号は全ての個別画像で同一の値を埋め込む必要があるため、 本関数は、@ref StartMpEncoderFirst を呼ぶ前に呼んでください。 @ref StartMpEncoderNext を呼ぶ前に本関数を呼んでも無視されます。 全ての個別画像のエンコードが終了後、成功、失敗問わず本関数の指定はクリアされます。 他にも、@ref ClearMpBaseViewpointNum を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] value 基準視点番号を指定します。 @return なし。 */ void SetMpBaseViewpointNum(u32 value) { if (m_Initialized) { m_TemporarySetting.mpAttribute.baseViewpointNum = value; m_TemporarySetting.mpAttribute.isBaseViewpointNumValid = true; } } /*! @brief MP個別情報IFDに埋め込む、基準視点番号をデフォルト値に戻します。 @return なし。 */ void ClearMpBaseViewpointNum() { if (m_Initialized) { m_TemporarySetting.mpAttribute.isBaseViewpointNumValid = false; } } /*! @brief MP個別情報IFDに埋め込む、輻輳角を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます) 本関数を呼ばない場合、ライブラリがデフォルト値(0xFFFFFFFF/0xFFFFFFFF)を登録します。 ただし、画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpConvergenceAngle を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue 輻輳角を指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpConvergenceAngle(const Srational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.convergenceAngle = *pValue; m_TemporarySetting.mpAttribute.isConvergenceAngleValid = true; } else { m_TemporarySetting.mpAttribute.isConvergenceAngleValid = false; } } } /*! @brief MP個別情報IFDに埋め込む、輻輳角をデフォルト値に戻します。 @return なし。 */ void ClearMpConvergenceAngle() { SetMpConvergenceAngle(NULL); } /*! @brief MP個別情報IFDに埋め込む、基線長を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。(デフォルト値が登録されます) 本関数を呼ばない場合、ライブラリがデフォルト値(0xFFFFFFFF/0xFFFFFFFF)を登録します。 ただし、画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpBaselineLength を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue 基線長を指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpBaselineLength(const Rational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.baselineLength = *pValue; m_TemporarySetting.mpAttribute.isBaselineLengthValid = true; } else { m_TemporarySetting.mpAttribute.isBaselineLengthValid = false; } } } /*! @brief MP個別情報IFDに埋め込む、基線長をデフォルト値に戻します。 @return なし。 */ void ClearMpBaselineLength() { SetMpBaselineLength(NULL); } /*! @brief MP個別情報IFDに埋め込む、水平からのずれを登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpVerticalDivergence を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue 水平からのずれを指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpVerticalDivergence(const Srational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.verticalDivergence = *pValue; m_TemporarySetting.mpAttribute.isVerticalDivergenceValid = true; } else { m_TemporarySetting.mpAttribute.isVerticalDivergenceValid = false; } } } /*! @brief MP個別情報IFDに水平からのずれを埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpVerticalDivergence() { SetMpVerticalDivergence(NULL); } /*! @brief MP個別情報IFDに埋め込む、水平軸方向の距離(X)を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpAxisDistanceX を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue 水平軸方向の距離(X)を指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpAxisDistanceX(const Srational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.axisDistanceX = *pValue; m_TemporarySetting.mpAttribute.isAxisDistanceXValid = true; } else { m_TemporarySetting.mpAttribute.isAxisDistanceXValid = false; } } } /*! @brief MP個別情報IFDに水平軸方向の距離(X)を埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpAxisDistanceX() { SetMpAxisDistanceX(NULL); } /*! @brief MP個別情報IFDに埋め込む、鉛直軸方向の距離(Y)を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpAxisDistanceY を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue 鉛直軸方向の距離(Y)を指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpAxisDistanceY(const Srational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.axisDistanceY = *pValue; m_TemporarySetting.mpAttribute.isAxisDistanceYValid = true; } else { m_TemporarySetting.mpAttribute.isAxisDistanceYValid = false; } } } /*! @brief MP個別情報IFDに鉛直軸方向の距離(Y)を埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpAxisDistanceY() { SetMpAxisDistanceY(NULL); } /*! @brief MP個別情報IFDに埋め込む、視準軸方向の距離(Z)を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpAxisDistanceZ を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue 視準軸方向の距離(Z)を指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpAxisDistanceZ(const Srational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.axisDistanceZ = *pValue; m_TemporarySetting.mpAttribute.isAxisDistanceZValid = true; } else { m_TemporarySetting.mpAttribute.isAxisDistanceZValid = false; } } } /*! @brief MP個別情報IFDに視準軸方向の距離(Z)を埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpAxisDistanceZ() { SetMpAxisDistanceZ(NULL); } /*! @brief MP個別情報IFDに埋め込む、ヨー角を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpYawAngle を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue ヨー角を指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpYawAngle(const Srational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.yawAngle = *pValue; m_TemporarySetting.mpAttribute.isYawAngleValid = true; } else { m_TemporarySetting.mpAttribute.isYawAngleValid = false; } } } /*! @brief MP個別情報IFDにヨー角を埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpYawAngle() { SetMpYawAngle(NULL); } /*! @brief MP個別情報IFDに埋め込む、ピッチ角を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpPitchAngle を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue ピッチ角を指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpPitchAngle(const Srational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.pitchAngle = *pValue; m_TemporarySetting.mpAttribute.isPitchAngleValid = true; } else { m_TemporarySetting.mpAttribute.isPitchAngleValid = false; } } } /*! @brief MP個別情報IFDにピッチ角を埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpPitchAngle() { SetMpPitchAngle(NULL); } /*! @brief MP個別情報IFDに埋め込む、ロール角を登録します。 本関数はエンコード関数として @ref StartMpEncoderFirst および @ref StartMpEncoderNext を使う場合に有効です。 @ref StartMpEncoderLR を使う場合には無効です。 本関数を呼ばない場合、あるいは画像のMP種別が @ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像) でない場合、値は埋め込まれません。 本関数は、エンコード関数を呼ぶ前に呼んでください。 エンコード関数終了後、成功、失敗問わず本関数の指定はクリアされます。 複数回エンコードする場合は、それぞれのエンコード前に本関数を呼ぶ必要があります。 他にも、引数 pValue にNULLを指定するか、@ref ClearMpRollAngle を呼ぶか、 @ref Initialize でエンコーダオブジェクトを再初期化すると指定はクリアされます。 @param[in] pValue ロール角を指定します。 NULLを指定するとクリアします。 @return なし。 */ void SetMpRollAngle(const Srational* pValue) { if (m_Initialized) { if (pValue) { m_TemporarySetting.mpAttribute.rollAngle = *pValue; m_TemporarySetting.mpAttribute.isRollAngleValid = true; } else { m_TemporarySetting.mpAttribute.isRollAngleValid = false; } } } /*! @brief MP個別情報IFDにロール角を埋め込まないよう指示します。(デフォルト動作) @return なし。 */ void ClearMpRollAngle() { SetMpRollAngle(NULL); } /*! @brief JPEGエンコードを実行し、MPフォーマットの先頭画像として格納します。 本関数では1組のMPフォーマットデータ(マルチピクチャオブジェクト、以下「MPO」) に含む合計画像数の指定と、先頭画像のエンコードを行います。 2枚目から合計画像数までのエンコードを行うためには、@ref StartMpEncoderNext を呼んでください。 後続の @ref StartMpEncoderNext のエンコード結果に応じて、本関数でエンコードした先頭画像のAPP2 (MPインデックスIFDやMPエントリ、MP個別情報IFDを含みます)が書き換えられます。 指定した合計画像数のエンコード途中で失敗した場合や、エンコードを中止した場合は、 先頭画像からエンコードをやり直す必要があります。 @ref StartMpEncoderLR と異なり、@ref SetUserMakerNote 、@ref SetMpTypeFlags 、@ref SetDateTime 等を呼んで、画像毎に各種データを登録できます。 2枚目以降に各種データを登録する場合、@ref StartMpEncoderNext を呼ぶ前にそれらの関数を呼ぶ必要があります。 また、@ref SetThumbnailSize および @ref SetInputBufferWidth の指定も画像毎になります。 2枚目以降に指定を行う場合、@ref StartMpEncoderNext を呼ぶ前にそれらの関数を呼ぶ必要があります。 本関数でエンコードできる画像の縦横サイズは画像の出力形式(引数 dstPixelSampling)によって変わります。 @ref StartJpegEncoder と同じです。 引数 typeCode に @ref MP_TYPE_CODE_BASELINE_MP_PRIMARY_IMAGE (Baseline MP 主画像) を指定すると、Baseline MPフォーマットを使用します。 それ以外を指定すると、Extended MPフォーマットを使用します。
Baseline MPフォーマットではMP個別情報IFDを格納しませんので、以下の関数を呼んでも無効です。
@ref SetMpIndividualNum 、@ref SetMpPanOrientation 、@ref SetMpPanOverlapH 、@ref SetMpPanOverlapV 、 @ref SetMpBaseViewpointNum 、@ref SetMpConvergenceAngle 、@ref SetMpBaselineLength 、@ref SetMpVerticalDivergence 、 @ref SetMpAxisDistanceX 、@ref SetMpAxisDistanceY 、@ref SetMpAxisDistanceZ 、 @ref SetMpYawAngle 、@ref SetMpPitchAngle 、@ref SetMpRollAngle @param[out] dst エンコード結果を格納するバッファを指定します。
指定した合計画像数のエンコードが完了するまで、このバッファを保持しておく必要があります。 (エンコードを中止した場合は破棄できます) @param[in] limit dstのバイト数を指定します。 このバイト数を超えるとエンコードに失敗します。
指定した合計画像数のエンコード途中に @ref StartMpEncoderNext が失敗した場合、 このバイト数が不足している可能性があります。 @param[in] src エンコードする画像データバッファを指定します。 4バイトアラインメントが必要です。 @param[in] width 画像の横幅(pixel)を指定します。(65536未満) @param[in] height 画像の縦幅(pixel)を指定します。(65536未満) @param[in] quality エンコードのクオリティを指定します。
1~100 まで指定可能であり、100 に近づくほど高画質になりサイズが大きくなります。 @param[in] dstPixelSampling 画像の出力形式(画素サンプリング)を指定します。 @param[in] srcPixelFormat エンコードする画像の入力ピクセルフォーマットを指定します。 @param[in] addThumbnail サムネイルを付加するかどうかを指定します。 @param[in] numImages 1つのMPOに含む合計画像数を指定します。
MP種別が立体視用画像の場合は、2以上にする必要があります。
Baseline MP 主画像の場合は、3以下にする必要があります。
デフォルトは2です。 @param[in] typeCode MP種別を指定します。 以下のいずれかの値を指定できます。
@ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像)
@ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像)
@ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像)
@ref MP_TYPE_CODE_UNDEFINED (未定義種別)
@ref MP_TYPE_CODE_BASELINE_MP_PRIMARY_IMAGE (Baseline MP 主画像)
デフォルトは @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) です。 @param[in] addImageUidList 個別画像ユニークIDリストを付加するかどうかを指定します。
trueを指定すると付加し、falseを指定すると付加しません。
付加する値は、本関数および @ref StartMpEncoderNext を呼ぶ直前に @ref SetImageUid で指定した画像ユニークIDです。
@ref SetImageUid を呼ばなかった場合や、先頭画像の場合はNULL (全バイトが0)になります。
デフォルトはfalseです。 @param[in] addTotalFrames 撮影時総コマ数を付加するかどうかを指定します。
trueを指定すると付加し、falseを指定すると付加しません。
MP種別(引数 typeCode)が @ref MP_TYPE_CODE_BASELINE_MP_PRIMARY_IMAGE の場合、指定は無視され、撮影時総コマ数を付加しません。
付加する値は、通常は合計画像数になりますが、 本関数および @ref StartMpEncoderNext を呼ぶ直前に @ref SetMpIndividualNum で個別画像番号を0に指定した場合、 その画像はカウントされません。
2枚目以降の、MP種別が @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_1 あるいは @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_2 (モニタ表示用画像) である画像もカウントされません。
デフォルトはfalseです。 @return 成功した場合、生成されたMPOのバイト数を返します。 (ただし合計画像数が1より大きい場合、このMPOは未完成状態です)
失敗した場合、0を返します。 失敗の原因は @ref GetLastError で取得できます。 */ size_t StartMpEncoderFirst(u8* dst, size_t limit, const void* src, u32 width, u32 height, u32 quality, PixelSampling dstPixelSampling, PixelFormat srcPixelFormat, bool addThumbnail, u32 numImages = 2, MpTypeCode typeCode = MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE, bool addImageUidList = false, bool addTotalFrames = false); /*! @brief JPEGエンコードを実行し、直前の @ref StartMpEncoderFirst あるいは本関数によるエンコード結果に追記します。 それらの処理が失敗した場合は、本関数も失敗します。 (先頭画像からエンコードをやり直す必要があります) 本関数は、@ref StartMpEncoderFirst で指定した合計画像数が1より大きい場合、マルチピクチャオブジェクト(MPO) を完成させるため、(合計画像数-1)回呼ぶ必要があります。 必要回数を超えて呼ぶと失敗します。 エンコード途中で失敗した場合や、エンコードを中止する場合は、それ以降本関数を呼ぶ必要はありません。 途中でエンコーダオブジェクトを初期化するとエンコード結果の追記ができませんので、 本関数を呼ぶ前に @ref Initialize を呼ばないでください。 本関数のエンコード結果は、@ref StartMpEncoderFirst で指定したバッファとバイト数の範囲内で、 直前の画像エンコード結果に追記します。 追記先のバイトオフセット(バッファ先頭から)が2の倍数になるようパディングされます。 このため、直前の個別画像のEOIマーカと、今回の個別画像のSOIマーカの間に1バイトの0が挿入される場合があります。 追記後にはパディングされません。 @ref SetUserMakerNote 、@ref SetMpTypeFlags 、@ref SetDateTime 等で登録した各種データや、 @ref SetThumbnailSize および @ref SetInputBufferWidth の指定は、 終了後、成功、失敗問わずクリアされます。 複数回エンコードする場合は、それぞれの画像エンコード前にそれらの関数を呼ぶ必要があります。 先頭画像のMP種別が @ref MP_TYPE_CODE_BASELINE_MP_PRIMARY_IMAGE (Baseline MP 主画像)の場合、Baseline MPフォーマットを使用しますので、 MP個別情報IFDを格納しません。@ref StartMpEncoderFirst と同様に、MP個別情報IFDを登録する関数を呼んでも無効です。 MP種別が @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_1 あるいは @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_2 (モニタ表示用画像) の場合、APP1に記録するタグは以下のもののみとなります。 このため、モニタ表示用画像のエンコード直後に @ref GetMpRegionsToBuildJpegData を使ってJPEGデータの再構成はできません。 IFD0 の Exif IFD Pointer、 Exif Private Tag の MakerNote (メーカーノート登録時)、PixelXDimension (*)、PixelYDimension (*)、ImageUniqueID (画像ユニークID登録時)、 IFD1 の JPEGInterchangeFormat (サムネイル付加時)、JPEGInterchangeFormatLength (サムネイル付加時)。 (*) MPフォーマット規格では、これらのタグは「モニタ元画像と同じ場合、記録しないことを推奨する」となっています。 エンコードする画像サイズ(引数 width および height)が、モニタ元画像の画像サイズと同じかどうかはアプリケーションで確認してください。 引数 omitPixelDimensions にtrueを指定すると、記録しません。 @param[in] src エンコードする画像データバッファを指定します。 4バイトアラインメントが必要です。 @param[in] width 画像の横幅(pixel)を指定します。(65536未満) @param[in] height 画像の縦幅(pixel)を指定します。(65536未満) @param[in] quality エンコードのクオリティを指定します。
1~100 まで指定可能であり、100 に近づくほど高画質になりサイズが大きくなります。 @param[in] dstPixelSampling 画像の出力形式(画素サンプリング)を指定します。 @param[in] srcPixelFormat エンコードする画像の入力ピクセルフォーマットを指定します。 @param[in] addThumbnail サムネイルを付加するかどうかを指定します。 @param[in] typeCode MP種別を指定します。 以下のいずれかの値を指定できます。
@ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像)
@ref MP_TYPE_CODE_MULTI_VIEW_PANORAMA_IMAGE (パノラマ画像)
@ref MP_TYPE_CODE_MULTI_VIEW_MULTI_ANGLE_IMAGE (マルチアングル画像)
@ref MP_TYPE_CODE_UNDEFINED (未定義種別)
@ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_1 および @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_2 (モニタ表示用画像)
なお、モニタ表示用画像以外を指定する場合、先頭画像のMP種別と同じである必要があります。
デフォルトは @ref MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE (立体視用画像) です。 @param[in] omitPixelDimensions MP種別(引数 typeCode)が @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_1 あるいは @ref MP_TYPE_CODE_LARGE_THUMBNAIL_IMAGE_CLASS_2 (モニタ表示用画像) の場合、APP1へ実効画像サイズ(PixelXDimension、PixelYDimension)の記録を省略するかどうかを指定します。
それ以外のMP種別では記録は省略できないため、指定は無視されます。
trueを指定すると省略し、falseを指定すると記録します。
デフォルトはfalseです。 @return 成功した場合、生成されたMPOのバイト数を返します。 (ただし必要回数の呼び出しが成功するまでは、このMPOは未完成状態です)
失敗した場合、0を返します。 失敗の原因は @ref GetLastError で取得できます。 */ size_t StartMpEncoderNext(const void* src, u32 width, u32 height, u32 quality, PixelSampling dstPixelSampling, PixelFormat srcPixelFormat, bool addThumbnail, MpTypeCode typeCode = MP_TYPE_CODE_MULTI_VIEW_DISPARITY_IMAGE, bool omitPixelDimensions = false); /*! @brief 直前の @ref StartMpEncoderFirst 、@ref StartMpEncoderNext あるいは @ref StartMpEncoderLR によるエンコード結果から、 JPEGデータを再構成するための領域情報を取得します。 それらの処理が失敗した場合は、本関数も失敗します。 直前に @ref StartJpegEncoder を呼んだ場合も失敗します。 直前に @ref StartMpEncoderNext でモニタ表示用画像をエンコードした場合も失敗します。 JPEGデータの再構成にはエンコード結果が必要です。破棄しないでください。 本関数は、同じ画像をMPフォーマットと、MPフォーマットではないJPEG形式で繰り返しエンコードする代わりに、 前者の結果を利用して高速に後者の結果を得るために使います。 MPフォーマットの個別画像データ構造は、簡単には「(JPEGヘッダ) + (APP2) + (JPEGデータ)」のようになっており、 APP2はMPフォーマット付属情報を含んでいます。 APP2を切り詰めれば、「(JPEGヘッダ) + (JPEGデータ)」となり、MPフォーマットではないJPEG形式でエンコードした結果と一致します。 本関数は、「(JPEGヘッダ)」と「(JPEGデータ)」の領域情報(ポインタとバイト数)を取得します。 直前に @ref StartMpEncoderLR を呼んだ場合、取得できるのは左目用画像の領域情報になります。 @param[out] pBuffer 領域情報を格納するバッファです。 @return 成功した場合、trueを返します。 失敗した場合、falseを返します。
失敗の原因は取得できません。本関数は @ref GetLastError が返す値を更新しません。 */ bool GetMpRegionsToBuildJpegData(MpRegionsToBuildJpegData* pBuffer); /*! @brief 直前の @ref StartMpEncoderFirst 、@ref StartMpEncoderNext あるいは @ref StartMpEncoderLR によるエンコードの失敗原因を取得します。 @return 直前のエンコードが成功した場合、@ref JPEG_ENCODER_ERROR_NONE (0) を返します。
エンコーダオブジェクトの初期化直後および再初期化直後も0を返します。
失敗した場合、0以外の値を返します。リファレンスは追って作成します。 */ s32 GetLastError() const; /*! @brief エンコーダオブジェクトの終了処理を行います。 @return なし。 */ void Finalize() { m_Initialized = false; } /*! @brief デストラクタです。 内部で Finalize() を呼びます。 */ ~JpegMpEncoder() { Finalize(); } protected: detail::JpegMpEncoderWorkObj* m_pWork; bool m_Initialized; bool m_Padding[3]; detail::JpegMpEncoderTemporarySettingObj m_TemporarySetting; void ClearTemporarySetting(); void SetMakerNote(const u8* pBuffer, size_t size, u32 index); }; } // namespace CTR { } // namespace jpeg { } // namespace nn { #endif // __cplusplus #endif // NN_JPEG_JPEGMPENCODER_H_