/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "aidl/android/hardware/graphics/common/Dataspace.h"
#include <ui/PublicFormat.h>


// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------

using ::aidl::android::hardware::graphics::common::Dataspace;

int mapPublicFormatToHalFormat(PublicFormat f) {
    switch (f) {
        case PublicFormat::JPEG:
        case PublicFormat::DEPTH_POINT_CLOUD:
        case PublicFormat::DEPTH_JPEG:
        case PublicFormat::HEIC:
        case PublicFormat::JPEG_R:
            return HAL_PIXEL_FORMAT_BLOB;
        case PublicFormat::DEPTH16:
            return HAL_PIXEL_FORMAT_Y16;
        case PublicFormat::RAW_SENSOR:
        case PublicFormat::RAW_DEPTH:
            return HAL_PIXEL_FORMAT_RAW16;
        case PublicFormat::RAW_DEPTH10:
            return HAL_PIXEL_FORMAT_RAW10;
        default:
            // Most formats map 1:1
            return static_cast<int>(f);
    }
}

android_dataspace mapPublicFormatToHalDataspace(PublicFormat f) {
    Dataspace dataspace;
    switch (f) {
        case PublicFormat::JPEG:
            dataspace = Dataspace::JFIF;
            break;
        case PublicFormat::DEPTH_POINT_CLOUD:
        case PublicFormat::DEPTH16:
        case PublicFormat::RAW_DEPTH:
        case PublicFormat::RAW_DEPTH10:
            dataspace = Dataspace::DEPTH;
            break;
        case PublicFormat::RAW_SENSOR:
        case PublicFormat::RAW_PRIVATE:
        case PublicFormat::RAW10:
        case PublicFormat::RAW12:
            dataspace = Dataspace::ARBITRARY;
            break;
        case PublicFormat::YUV_420_888:
        case PublicFormat::NV21:
        case PublicFormat::YV12:
            dataspace = Dataspace::JFIF;
            break;
        case PublicFormat::DEPTH_JPEG:
            dataspace = Dataspace::DYNAMIC_DEPTH;
            break;
        case PublicFormat::HEIC:
            dataspace = Dataspace::HEIF;
            break;
        case PublicFormat::JPEG_R:
            dataspace = Dataspace::JPEG_R;
            break;
        default:
            // Most formats map to UNKNOWN
            dataspace = Dataspace::UNKNOWN;
            break;
    }
    return static_cast<android_dataspace>(dataspace);
}

PublicFormat mapHalFormatDataspaceToPublicFormat(int format, android_dataspace dataSpace) {
    Dataspace ds = static_cast<Dataspace>(dataSpace);
    switch (format) {
        case HAL_PIXEL_FORMAT_RAW10:
            switch (ds) {
                case Dataspace::DEPTH:
                    return PublicFormat::RAW_DEPTH10;
                default:
                    return PublicFormat::RAW10;
            }
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_RGBA_FP16:
        case HAL_PIXEL_FORMAT_RGBA_1010102:
        case HAL_PIXEL_FORMAT_RGB_888:
        case HAL_PIXEL_FORMAT_RGB_565:
        case HAL_PIXEL_FORMAT_Y8:
        case HAL_PIXEL_FORMAT_RAW12:
        case HAL_PIXEL_FORMAT_YCbCr_420_888:
        case HAL_PIXEL_FORMAT_YV12:
        case HAL_PIXEL_FORMAT_YCBCR_P010:
            // Enums overlap in both name and value
            return static_cast<PublicFormat>(format);
        case HAL_PIXEL_FORMAT_RAW16:
            switch (ds) {
                case Dataspace::DEPTH:
                    return PublicFormat::RAW_DEPTH;
                default:
                    return PublicFormat::RAW_SENSOR;
            }
        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
            // Name differs, though value is the same
            return PublicFormat::RAW_PRIVATE;
        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
            // Name differs, though the value is the same
            return PublicFormat::NV16;
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            // Name differs, though the value is the same
            return PublicFormat::NV21;
        case HAL_PIXEL_FORMAT_YCbCr_422_I:
            // Name differs, though the value is the same
            return PublicFormat::YUY2;
        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
            // Name differs, though the value is the same
            return PublicFormat::PRIVATE;
        case HAL_PIXEL_FORMAT_Y16:
            // Dataspace-dependent
            switch (ds) {
                case Dataspace::DEPTH:
                    return PublicFormat::DEPTH16;
                default:
                    // Assume non-depth Y16 is just Y16.
                    return PublicFormat::Y16;
            }
        case HAL_PIXEL_FORMAT_BLOB:
            // Dataspace-dependent
            switch (ds) {
                case Dataspace::DEPTH:
                    return PublicFormat::DEPTH_POINT_CLOUD;
                case Dataspace::JFIF:
                    return PublicFormat::JPEG;
                case Dataspace::HEIF:
                    return PublicFormat::HEIC;
                default:
                    if (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_DYNAMIC_DEPTH)) {
                        return PublicFormat::DEPTH_JPEG;
                    } else if (dataSpace == static_cast<android_dataspace>(Dataspace::JPEG_R)) {
                        return PublicFormat::JPEG_R;
                    }else {
                        // Assume otherwise-marked blobs are also JPEG
                        return PublicFormat::JPEG;
                    }
            }
        case HAL_PIXEL_FORMAT_BGRA_8888:
            // Not defined in public API
            return PublicFormat::UNKNOWN;

        default:
            return PublicFormat::UNKNOWN;
    }
}

// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
