/* Copyright (C) 2000-2003 Constantin Kaplinsky.  All Rights Reserved.
 * Copyright (C) 2004-2005 Cendio AB. All rights reserved.
 * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
 * Copyright (C) 2020-2026 m-privacy GmbH. All Rights Reserved.
 * 
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 * USA.
 */

//
// MPDecompressor decompresses a MP image into RGB output
// an underlying MemOutStream
//

#ifndef __RFB_MP_H__
#define __RFB_MP_H__

#if !defined(__APPLE__) && !defined(WIN32)
#include <rfb/LogWriter.h>
#include <string.h>
#include <stdio.h>

static rfb::LogWriter mplog("MP");
#endif

#define MP_COMPRESSION_MIN_OPT_SIZE 128
#define MP_COMPRESSION_MIN_SAVE_SIZE 32

/* flags transmitted as xor'd U8 */
//#define MP_COMPRESSION_FLAG_DOUBLE 1
//#define MP_COMPRESSION_FLAG_QUAD 2

/* compression type transmitted as U8, possible values 0-255 */
#define MP_COMPRESSION_AUTO 0
//#define MP_COMPRESSION_HEIF_MIN 1
//#define MP_COMPRESSION_HEIF_HEVC 1
//#define MP_COMPRESSION_HEIF_AV1 4
//#define MP_COMPRESSION_HEIF_MAX 4
#define MP_COMPRESSION_H264 10
#define MP_COMPRESSION_JPEG 11
#define MP_COMPRESSION_RAW 12
#define MP_COMPRESSION_RAWI420 13
#define MP_COMPRESSION_SOLID 14
#define MP_COMPRESSION_ZSTD 15
#define MP_COMPRESSION_I420ZSTD 16
//#define MP_COMPRESSION_JPEG2000 17
#define MP_COMPRESSION_JPEGLB 18
//#define MP_COMPRESSION_WEBP 19
//#define MP_COMPRESSION_WEBPLL 20
//#if !defined(__APPLE__)
//#define MP_COMPRESSION_JPEGXL 21
//#endif
//#define MP_COMPRESSION_JPEGXLLB 22
//#define MP_COMPRESSION_JPEGXLXLB 23
#define MP_COMPRESSION_H264_I420 24
//#define MP_COMPRESSION_VPX_420 25
//#define MP_COMPRESSION_VPX_422 26
//#define MP_COMPRESSION_VPX_444 27
#define MP_COMPRESSION_RAWI422 28
#define MP_COMPRESSION_RAWI444 29
#define MP_COMPRESSION_I422ZSTD 30
#define MP_COMPRESSION_I444ZSTD 31
#define MP_COMPRESSION_H264_I422 32
#define MP_COMPRESSION_H264_I444 33

#define MP_COMPRESSION_MIN 0
#define MP_COMPRESSION_MAX 33
#define MP_COMPRESSION_DEFAULT MP_COMPRESSION_AUTO

static inline bool mpCompressionValid(int number)
{
	switch(number) {
		case MP_COMPRESSION_AUTO:
		case MP_COMPRESSION_JPEG:
		case MP_COMPRESSION_RAW:
		case MP_COMPRESSION_RAWI420:
		case MP_COMPRESSION_ZSTD:
		case MP_COMPRESSION_I420ZSTD:
		case MP_COMPRESSION_H264:
		case MP_COMPRESSION_H264_I420:
		case MP_COMPRESSION_H264_I444:
		case MP_COMPRESSION_JPEGLB:
		case MP_COMPRESSION_RAWI444:
		case MP_COMPRESSION_I444ZSTD:
			return true;
		default:
			return false;
	}
}

static inline const char * mpCompressionName(int number)
{
	switch(number) {
		case MP_COMPRESSION_AUTO:
			return "Auto";
		case MP_COMPRESSION_H264:
			return "H.264/Auto";
		case MP_COMPRESSION_JPEG:
			return "JPEG";
		case MP_COMPRESSION_JPEGLB:
			return "JPEG Low Bandwidth";
		case MP_COMPRESSION_RAW:
			return "RAW";
		case MP_COMPRESSION_RAWI420:
			return "I420";
		case MP_COMPRESSION_ZSTD:
			return "ZSTD";
		case MP_COMPRESSION_I420ZSTD:
			return "ZSTD/I420";
		case MP_COMPRESSION_SOLID:
			return "Solid Rect";
		case MP_COMPRESSION_H264_I420:
			return "H.264/I420";
		case MP_COMPRESSION_H264_I422:
			return "H.264/I422";
		case MP_COMPRESSION_H264_I444:
			return "H.264/I444";
		case MP_COMPRESSION_RAWI422:
			return "I422";
		case MP_COMPRESSION_RAWI444:
			return "I444";
		case MP_COMPRESSION_I422ZSTD:
			return "ZSTD/I422";
		case MP_COMPRESSION_I444ZSTD:
			return "ZSTD/I444";
		default:
			return "Unknown";
	}
}

#ifndef likely
#ifdef __GNUC__
#define likely(x)   __builtin_expect (!!(x), 1)
#else
#define likely(x)   (x)
#endif
#endif
#ifndef unlikely
#ifdef __GNUC__
#define unlikely(x) __builtin_expect (!!(x), 0)
#else
#define unlikely(x) (x)
#endif
#endif

#endif
