summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--include/aspeed/JTABLES.H299
-rw-r--r--include/ast_jpeg_decoder.hpp1547
-rw-r--r--include/kvm_websocket.hpp173
-rw-r--r--include/security_headers_middleware.hpp7
-rw-r--r--include/web_kvm.hpp422
-rw-r--r--src/getvideo_main.cpp79
-rw-r--r--src/webserver_main.cpp4
8 files changed, 182 insertions, 2354 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6756575c27..a15e7197c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ option (BUILD_STATIC_LIBS "Built static libraries" ON)
option (YOCTO_DEPENDENCIES "Use YOCTO dependencies system" OFF)
option (BMCWEB_ENABLE_KVM "Enable the KVM host video WebSocket. Path is
- '/kvmws'. Video is from the BMC's '/dev/video' device." ON)
+ '/kvm/0'. Video is from the BMC's '/dev/video' device." ON)
option (BMCWEB_ENABLE_DBUS_REST "Enable Phosphor REST (D-Bus) APIs. Paths
directly map Phosphor D-Bus object paths, for example,
'/xyz/openbmc_project/logging/entry/enumerate'. See
@@ -248,9 +248,6 @@ target_link_libraries (bmcweb sdbusplus)
target_link_libraries (bmcweb tinyxml2)
install (TARGETS bmcweb DESTINATION bin)
-add_executable (getvideo src/getvideo_main.cpp)
-target_link_libraries (getvideo pthread)
-
target_compile_definitions (
bmcweb PRIVATE
$<$<BOOL:${BMCWEB_ENABLE_KVM}>: -DBMCWEB_ENABLE_KVM>
diff --git a/include/aspeed/JTABLES.H b/include/aspeed/JTABLES.H
deleted file mode 100644
index 641fcfb76a..0000000000
--- a/include/aspeed/JTABLES.H
+++ /dev/null
@@ -1,299 +0,0 @@
-#pragma once
-static const unsigned char zigzag[64] = {
- 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42,
- 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53,
- 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60,
- 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63};
-
-static const unsigned char dezigzag[64 + 15] = {
- 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40,
- 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36,
- 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61,
- 54, 47, 55, 62, 63,
- // let corrupt input sample past end
- 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63};
-
-static const unsigned char *stdLuminanceQt;
-static const unsigned char *stdChrominanceQt;
-
-// Standard Huffman tables (cf. JPEG standard section K.3) */
-
-static const unsigned char stdDcLuminanceNrcodes[17] = {
- 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0};
-static const unsigned char stdDcLuminanceValues[12] = {0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10, 11};
-
-static const unsigned char stdDcChrominanceNrcodes[17] = {
- 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
-static const unsigned char stdDcChrominanceValues[12] = {0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10, 11};
-
-static const unsigned char stdAcLuminanceNrcodes[17] = {
- 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d};
-static const unsigned char stdAcLuminanceValues[162] = {
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
- 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
- 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
- 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
- 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
- 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
- 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
- 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
- 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
-
-static const unsigned char stdAcChrominanceNrcodes[17] = {
- 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77};
-static const unsigned char stdAcChrominanceValues[162] = {
- 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
- 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
- 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
- 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
- 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,
- 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74,
- 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
- 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
- 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
- 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
- 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
-
-static const unsigned short int dcLuminanceHuffmancode[13 * 2] = {
- /* 0 */ 0x0000, 0,
- /* 1 */ 0x4000, 2,
- /* 2 */ 0x6000, 3,
- /* 3 */ 0x8000, 3,
- /* 4 */ 0xA000, 3,
- /* 5 */ 0xC000, 3,
- /* 6 */ 0xE000, 3,
- /* 7 */ 0xF000, 4,
- /* 8 */ 0xF800, 5,
- /* 9 */ 0xFC00, 6,
- /* 10 */ 0xFE00, 7,
- /* 11 */ 0xFF00, 8,
- /* 12 */ 0xFFFF, 9,
-};
-
-static const unsigned short int dcChrominanceHuffmancode[13 * 2] = {
- /* 0 */ 0x0000, 0,
- /* 1 */ 0x4000, 2,
- /* 2 */ 0x8000, 2,
- /* 3 */ 0xC000, 2,
- /* 4 */ 0xE000, 3,
- /* 5 */ 0xF000, 4,
- /* 6 */ 0xF800, 5,
- /* 7 */ 0xFC00, 6,
- /* 8 */ 0xFE00, 7,
- /* 9 */ 0xFF00, 8,
- /* 10 */ 0xFF80, 9,
- /* 11 */ 0xFFC0, 10,
- /* 12 */ 0xFFFF, 11,
-};
-
-static const unsigned short int acLuminanceHuffmancode[39 * 2] = {
- /* 0 */ 0x0000, 0,
- /* 1 */ 0x4000, 2,
- /* 2 */ 0x8000, 2,
- /* 3 */ 0xA000, 3,
- /* 4 */ 0xB000, 4,
- /* 5 */ 0xC000, 4,
- /* 6 */ 0xD000, 4,
- /* 7 */ 0xD800, 5,
- /* 8 */ 0xE000, 5,
- /* 9 */ 0xE800, 5,
- /* 10 */ 0xEC00, 6,
- /* 11 */ 0xF000, 6,
- /* 12 */ 0xF200, 7,
- /* 13 */ 0xF400, 7,
- /* 14 */ 0xF600, 7,
- /* 15 */ 0xF800, 7,
- /* 16 */ 0xF900, 8,
- /* 17 */ 0xFA00, 8,
- /* 18 */ 0xFB00, 8,
- /* 19 */ 0xFB80, 9,
- /* 20 */ 0xFC00, 9,
- /* 21 */ 0xFC80, 9,
- /* 22 */ 0xFD00, 9,
- /* 23 */ 0xFD80, 9,
- /* 24 */ 0xFDC0, 10,
- /* 25 */ 0xFE00, 10,
- /* 26 */ 0xFE40, 10,
- /* 27 */ 0xFE80, 10,
- /* 28 */ 0xFEC0, 10,
- /* 29 */ 0xFEE0, 11,
- /* 30 */ 0xFF00, 11,
- /* 31 */ 0xFF20, 11,
- /* 32 */ 0xFF40, 11,
- /* 33 */ 0xFF50, 12,
- /* 34 */ 0xFF60, 12,
- /* 35 */ 0xFF70, 12,
- /* 36 */ 0xFF80, 12,
- /* 37 */ 0xFF82, 15,
- /* 38 */ 0xFFFF, 16,
-};
-
-static const unsigned short int acChrominanceHuffmancode[45 * 2] = {
- /* 0 */ 0x0000, 0,
- /* 1 */ 0x4000, 2,
- /* 2 */ 0x8000, 2,
- /* 3 */ 0xA000, 3,
- /* 4 */ 0xB000, 4,
- /* 5 */ 0xC000, 4,
- /* 6 */ 0xC800, 5,
- /* 7 */ 0xD000, 5,
- /* 8 */ 0xD800, 5,
- /* 9 */ 0xE000, 5,
- /* 10 */ 0xE400, 6,
- /* 11 */ 0xE800, 6,
- /* 12 */ 0xEC00, 6,
- /* 13 */ 0xF000, 6,
- /* 14 */ 0xF200, 7,
- /* 15 */ 0xF400, 7,
- /* 16 */ 0xF600, 7,
- /* 17 */ 0xF700, 8,
- /* 18 */ 0xF800, 8,
- /* 19 */ 0xF900, 8,
- /* 20 */ 0xFA00, 8,
- /* 21 */ 0xFA80, 9,
- /* 22 */ 0xFB00, 9,
- /* 23 */ 0xFB80, 9,
- /* 24 */ 0xFC00, 9,
- /* 25 */ 0xFC80, 9,
- /* 26 */ 0xFD00, 9,
- /* 27 */ 0xFD80, 9,
- /* 28 */ 0xFDC0, 10,
- /* 29 */ 0xFE00, 10,
- /* 30 */ 0xFE40, 10,
- /* 31 */ 0xFE80, 10,
- /* 32 */ 0xFEC0, 10,
- /* 33 */ 0xFEE0, 11,
- /* 34 */ 0xFF00, 11,
- /* 35 */ 0xFF20, 11,
- /* 36 */ 0xFF40, 11,
- /* 37 */ 0xFF50, 12,
- /* 38 */ 0xFF60, 12,
- /* 39 */ 0xFF70, 12,
- /* 40 */ 0xFF80, 12,
- /* 41 */ 0xFF84, 14,
- /* 42 */ 0xFF86, 15,
- /* 43 */ 0xFF88, 15,
- /* 44 */ 0xFFFF, 16,
-};
-
-//[100]=========================
-static const unsigned char tbl100Y[64] = {
- 2, 1, 1, 2, 3, 5, 6, 7, 1, 1, 1, 2, 3, 7, 7, 6,
- 1, 1, 2, 3, 5, 7, 8, 7, 1, 2, 2, 3, 6, 10, 10, 7,
- 2, 2, 4, 7, 8, 13, 12, 9, 3, 4, 6, 8, 10, 13, 14, 11,
- 6, 8, 9, 10, 12, 15, 15, 12, 9, 11, 11, 12, 14, 12, 12, 12};
-static const unsigned char tbl100Uv[64] = {
- 3, 3, 4, 8, 18, 18, 18, 18, 3, 3, 4, 12, 18, 18, 18, 18,
- 4, 4, 10, 18, 18, 18, 18, 18, 8, 12, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18};
-
-//[086]=========================
-static const unsigned char tbl086Y[64] = {
- 3, 2, 1, 3, 4, 7, 9, 11, 2, 2, 2, 3, 4, 10, 11, 10,
- 2, 2, 3, 4, 7, 10, 12, 10, 2, 3, 4, 5, 9, 16, 15, 11,
- 3, 4, 6, 10, 12, 20, 19, 14, 4, 6, 10, 12, 15, 19, 21, 17,
- 9, 12, 14, 16, 19, 22, 22, 18, 13, 17, 17, 18, 21, 18, 19, 18};
-static const unsigned char tbl086Uv[64] = {
- 4, 5, 6, 13, 27, 27, 27, 27, 5, 5, 7, 18, 27, 27, 27, 27,
- 6, 7, 15, 27, 27, 27, 27, 27, 13, 18, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27};
-
-//[071]=========================
-static const unsigned char tbl071Y[64] = {
- 6, 4, 3, 6, 9, 15, 19, 22, 4, 4, 5, 7, 9, 21, 22, 20,
- 5, 4, 6, 9, 15, 21, 25, 21, 5, 6, 8, 10, 19, 32, 30, 23,
- 6, 8, 13, 21, 25, 40, 38, 28, 9, 13, 20, 24, 30, 39, 42, 34,
- 18, 24, 29, 32, 38, 45, 45, 37, 27, 34, 35, 36, 42, 37, 38, 37};
-static const unsigned char tbl071Uv[64] = {
- 9, 10, 13, 26, 55, 55, 55, 55, 10, 11, 14, 37, 55, 55, 55, 55,
- 13, 14, 31, 55, 55, 55, 55, 55, 26, 37, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55};
-//[057]=========================
-static const unsigned char tbl057Y[64] = {
- 9, 6, 5, 9, 13, 22, 28, 34, 6, 6, 7, 10, 14, 32, 33, 30,
- 7, 7, 9, 13, 22, 32, 38, 31, 7, 9, 12, 16, 28, 48, 45, 34,
- 10, 12, 20, 31, 38, 61, 57, 43, 13, 19, 30, 36, 45, 58, 63, 51,
- 27, 36, 43, 48, 57, 68, 67, 56, 40, 51, 53, 55, 63, 56, 57, 55};
-static const unsigned char tbl057Uv[64] = {
- 13, 14, 19, 38, 80, 80, 80, 80, 14, 17, 21, 53, 80, 80, 80, 80,
- 19, 21, 45, 80, 80, 80, 80, 80, 38, 53, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80};
-
-//[043]=========================
-static const unsigned char tbl043Y[64] = {
- 11, 7, 7, 11, 17, 28, 36, 43, 8, 8, 10, 13, 18, 41, 43, 39,
- 10, 9, 11, 17, 28, 40, 49, 40, 10, 12, 15, 20, 36, 62, 57, 44,
- 12, 15, 26, 40, 48, 78, 74, 55, 17, 25, 39, 46, 58, 74, 81, 66,
- 35, 46, 56, 62, 74, 86, 86, 72, 51, 66, 68, 70, 80, 71, 74, 71};
-static const unsigned char tbl043Uv[64] = {
- 18, 19, 26, 51, 108, 108, 108, 108, 19, 22, 28, 72, 108,
- 108, 108, 108, 26, 28, 61, 108, 108, 108, 108, 108, 51, 72,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108};
-
-//[029]=========================
-static const unsigned char tbl029Y[64] = {
- 14, 9, 9, 14, 21, 36, 46, 55, 10, 10, 12, 17, 23, 52, 54, 49,
- 12, 11, 14, 21, 36, 51, 62, 50, 12, 15, 19, 26, 46, 78, 72, 56,
- 16, 19, 33, 50, 61, 98, 93, 69, 21, 31, 49, 58, 73, 94, 102, 83,
- 44, 58, 70, 78, 93, 109, 108, 91, 65, 83, 86, 88, 101, 90, 93, 89};
-static const unsigned char tbl029Uv[64] = {
- 22, 24, 32, 63, 133, 133, 133, 133, 24, 28, 34, 88, 133,
- 133, 133, 133, 32, 34, 75, 133, 133, 133, 133, 133, 63, 88,
- 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
- 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
- 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133};
-
-//[014]=========================
-static const unsigned char tbl014Y[64] = {
- 17, 12, 10, 17, 26, 43, 55, 66, 13, 13, 15, 20, 28, 63, 65, 60,
- 15, 14, 17, 26, 43, 62, 75, 61, 15, 18, 24, 31, 55, 95, 87, 67,
- 19, 24, 40, 61, 74, 119, 112, 84, 26, 38, 60, 70, 88, 113, 123, 100,
- 53, 70, 85, 95, 112, 132, 131, 110, 78, 100, 103, 107, 122, 109, 112, 108};
-static const unsigned char tbl014Uv[64] = {
- 27, 29, 39, 76, 160, 160, 160, 160, 29, 34, 42, 107, 160,
- 160, 160, 160, 39, 42, 91, 160, 160, 160, 160, 160, 76, 107,
- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160};
-//[000]=========================
-static const unsigned char tbl000Y[64] = {
- 20, 13, 12, 20, 30, 50, 63, 76, 15, 15, 17, 23, 32, 72, 75, 68,
- 17, 16, 20, 30, 50, 71, 86, 70, 17, 21, 27, 36, 63, 108, 100, 77,
- 22, 27, 46, 70, 85, 136, 128, 96, 30, 43, 68, 80, 101, 130, 141, 115,
- 61, 80, 97, 108, 128, 151, 150, 126, 90, 115, 118, 122, 140, 125, 128, 123};
-static const unsigned char tbl000Uv[64] = {
- 31, 33, 45, 88, 185, 185, 185, 185, 33, 39, 48, 123, 185,
- 185, 185, 185, 45, 48, 105, 185, 185, 185, 185, 185, 88, 123,
- 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
- 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
- 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185};
-
-struct HuffmanTable {
- unsigned char length[17]; // k =1-16 ; L[k] indicates the number of Huffman
- // codes of length k
- unsigned short int minorCode[17]; // indicates the value of the smallest
- // Huffman code of length k
- unsigned short int majorCode[17]; // similar, but the highest code
- unsigned char v[65536]; // V[k][j] = Value associated to the j-th Huffman
- // code of length k
- // High nibble = nr of previous 0 coefficients
- // Low nibble = size (in bits) of the coefficient which will be taken from the
- // data stream
- unsigned char len[65536];
-};
diff --git a/include/ast_jpeg_decoder.hpp b/include/ast_jpeg_decoder.hpp
deleted file mode 100644
index e8bdddbf59..0000000000
--- a/include/ast_jpeg_decoder.hpp
+++ /dev/null
@@ -1,1547 +0,0 @@
-#pragma once
-
-#include <aspeed/JTABLES.H>
-
-#include <array>
-#include <ast_video_types.hpp>
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-#include <iostream>
-#include <vector>
-
-namespace ast_video
-{
-
-struct ColorCache
-{
- ColorCache() :
- color{0x008080, 0xFF8080, 0x808080, 0xC08080}, index{0, 1, 2, 3}
- {
- }
-
- unsigned long color[4];
- unsigned char index[4];
- unsigned char bitMapBits{};
-};
-
-struct RGB
-{
- unsigned char b;
- unsigned char g;
- unsigned char r;
- unsigned char reserved;
-};
-
-enum class JpgBlock
-{
- JPEG_NO_SKIP_CODE = 0x00,
- JPEG_SKIP_CODE = 0x08,
-
- JPEG_PASS2_CODE = 0x02,
- JPEG_SKIP_PASS2_CODE = 0x0A,
-
- LOW_JPEG_NO_SKIP_CODE = 0x04,
- LOW_JPEG_SKIP_CODE = 0x0C,
-
- VQ_NO_SKIP_1_COLOR_CODE = 0x05,
- VQ_SKIP_1_COLOR_CODE = 0x0D,
-
- VQ_NO_SKIP_2_COLOR_CODE = 0x06,
- VQ_SKIP_2_COLOR_CODE = 0x0E,
-
- VQ_NO_SKIP_4_COLOR_CODE = 0x07,
- VQ_SKIP_4_COLOR_CODE = 0x0F,
-
- FRAME_END_CODE = 0x09,
-
-};
-
-class AstJpegDecoder
-{
- public:
- AstJpegDecoder()
- {
- // TODO(ed) figure out how to init this in the constructor
- yuvBuffer.resize(1920 * 1200);
- outBuffer.resize(1920 * 1200);
- for (auto &r : outBuffer)
- {
- r.r = 0x00;
- r.g = 0x00;
- r.b = 0x00;
- r.reserved = 0xAA;
- }
-
- int qfactor = 16;
-
- scalefactor = qfactor;
- scalefactoruv = qfactor;
- advancescalefactor = 16;
- advancescalefactoruv = 16;
- initJpgTable();
- }
-
- void loadQuantTable(std::array<long, 64> &quant_table)
- {
- float scalefactorF[8] = {1.0f, 1.387039845f, 1.306562965f,
- 1.175875602f, 1.0f, 0.785694958f,
- 0.541196100f, 0.275899379f};
- uint8_t j, row, col;
- std::array<uint8_t, 64> tempQT{};
-
- // Load quantization coefficients from JPG file, scale them for DCT and
- // reorder
- // from zig-zag order
- switch (ySelector)
- {
- case 0:
- stdLuminanceQt = tbl000Y;
- break;
- case 1:
- stdLuminanceQt = tbl014Y;
- break;
- case 2:
- stdLuminanceQt = tbl029Y;
- break;
- case 3:
- stdLuminanceQt = tbl043Y;
- break;
- case 4:
- stdLuminanceQt = tbl057Y;
- break;
- case 5:
- stdLuminanceQt = tbl071Y;
- break;
- case 6:
- stdLuminanceQt = tbl086Y;
- break;
- case 7:
- stdLuminanceQt = tbl100Y;
- break;
- }
- setQuantTable(stdLuminanceQt, static_cast<uint8_t>(scalefactor),
- tempQT);
-
- for (j = 0; j <= 63; j++)
- {
- quant_table[j] = tempQT[zigzag[j]];
- }
- j = 0;
- for (row = 0; row <= 7; row++)
- {
- for (col = 0; col <= 7; col++)
- {
- quant_table[j] = static_cast<long>(
- (quant_table[j] * scalefactorF[row] * scalefactorF[col]) *
- 65536);
- j++;
- }
- }
- bytePos += 64;
- }
-
- void loadQuantTableCb(std::array<long, 64> &quant_table)
- {
- float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
- 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
- uint8_t j, row, col;
- std::array<uint8_t, 64> tempQT{};
-
- // Load quantization coefficients from JPG file, scale them for DCT and
- // reorder from zig-zag order
- if (mapping == 0)
- {
- switch (uvSelector)
- {
- case 0:
- stdChrominanceQt = tbl000Y;
- break;
- case 1:
- stdChrominanceQt = tbl014Y;
- break;
- case 2:
- stdChrominanceQt = tbl029Y;
- break;
- case 3:
- stdChrominanceQt = tbl043Y;
- break;
- case 4:
- stdChrominanceQt = tbl057Y;
- break;
- case 5:
- stdChrominanceQt = tbl071Y;
- break;
- case 6:
- stdChrominanceQt = tbl086Y;
- break;
- case 7:
- stdChrominanceQt = tbl100Y;
- break;
- }
- }
- else
- {
- switch (uvSelector)
- {
- case 0:
- stdChrominanceQt = tbl000Uv;
- break;
- case 1:
- stdChrominanceQt = tbl014Uv;
- break;
- case 2:
- stdChrominanceQt = tbl029Uv;
- break;
- case 3:
- stdChrominanceQt = tbl043Uv;
- break;
- case 4:
- stdChrominanceQt = tbl057Uv;
- break;
- case 5:
- stdChrominanceQt = tbl071Uv;
- break;
- case 6:
- stdChrominanceQt = tbl086Uv;
- break;
- case 7:
- stdChrominanceQt = tbl100Uv;
- break;
- }
- }
- setQuantTable(stdChrominanceQt, static_cast<uint8_t>(scalefactoruv),
- tempQT);
-
- for (j = 0; j <= 63; j++)
- {
- quant_table[j] = tempQT[zigzag[j]];
- }
- j = 0;
- for (row = 0; row <= 7; row++)
- {
- for (col = 0; col <= 7; col++)
- {
- quant_table[j] = static_cast<long>(
- (quant_table[j] * scalefactor[row] * scalefactor[col]) *
- 65536);
- j++;
- }
- }
- bytePos += 64;
- }
- // Note: Added for Dual_JPEG
- void loadAdvanceQuantTable(std::array<long, 64> &quant_table)
- {
- float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
- 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
- uint8_t j, row, col;
- std::array<uint8_t, 64> tempQT{};
-
- // Load quantization coefficients from JPG file, scale them for DCT and
- // reorder
- // from zig-zag order
- switch (advanceSelector)
- {
- case 0:
- stdLuminanceQt = tbl000Y;
- break;
- case 1:
- stdLuminanceQt = tbl014Y;
- break;
- case 2:
- stdLuminanceQt = tbl029Y;
- break;
- case 3:
- stdLuminanceQt = tbl043Y;
- break;
- case 4:
- stdLuminanceQt = tbl057Y;
- break;
- case 5:
- stdLuminanceQt = tbl071Y;
- break;
- case 6:
- stdLuminanceQt = tbl086Y;
- break;
- case 7:
- stdLuminanceQt = tbl100Y;
- break;
- }
- // Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
- setQuantTable(stdLuminanceQt, static_cast<uint8_t>(advancescalefactor),
- tempQT);
-
- for (j = 0; j <= 63; j++)
- {
- quant_table[j] = tempQT[zigzag[j]];
- }
- j = 0;
- for (row = 0; row <= 7; row++)
- {
- for (col = 0; col <= 7; col++)
- {
- quant_table[j] = static_cast<long>(
- (quant_table[j] * scalefactor[row] * scalefactor[col]) *
- 65536);
- j++;
- }
- }
- bytePos += 64;
- }
-
- // Note: Added for Dual-JPEG
- void loadAdvanceQuantTableCb(std::array<long, 64> &quant_table)
- {
- float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
- 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
- uint8_t j, row, col;
- std::array<uint8_t, 64> tempQT{};
-
- // Load quantization coefficients from JPG file, scale them for DCT and
- // reorder
- // from zig-zag order
- if (mapping == 1)
- {
- switch (advanceSelector)
- {
- case 0:
- stdChrominanceQt = tbl000Y;
- break;
- case 1:
- stdChrominanceQt = tbl014Y;
- break;
- case 2:
- stdChrominanceQt = tbl029Y;
- break;
- case 3:
- stdChrominanceQt = tbl043Y;
- break;
- case 4:
- stdChrominanceQt = tbl057Y;
- break;
- case 5:
- stdChrominanceQt = tbl071Y;
- break;
- case 6:
- stdChrominanceQt = tbl086Y;
- break;
- case 7:
- stdChrominanceQt = tbl100Y;
- break;
- }
- }
- else
- {
- switch (advanceSelector)
- {
- case 0:
- stdChrominanceQt = tbl000Uv;
- break;
- case 1:
- stdChrominanceQt = tbl014Uv;
- break;
- case 2:
- stdChrominanceQt = tbl029Uv;
- break;
- case 3:
- stdChrominanceQt = tbl043Uv;
- break;
- case 4:
- stdChrominanceQt = tbl057Uv;
- break;
- case 5:
- stdChrominanceQt = tbl071Uv;
- break;
- case 6:
- stdChrominanceQt = tbl086Uv;
- break;
- case 7:
- stdChrominanceQt = tbl100Uv;
- break;
- }
- }
- // Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
- setQuantTable(stdChrominanceQt,
- static_cast<uint8_t>(advancescalefactoruv), tempQT);
-
- for (j = 0; j <= 63; j++)
- {
- quant_table[j] = tempQT[zigzag[j]];
- }
- j = 0;
- for (row = 0; row <= 7; row++)
- {
- for (col = 0; col <= 7; col++)
- {
- quant_table[j] = static_cast<long>(
- (quant_table[j] * scalefactor[row] * scalefactor[col]) *
- 65536);
- j++;
- }
- }
- bytePos += 64;
- }
-
- void idctTransform(short *coef, uint8_t *data, uint8_t nBlock)
- {
-#define FIX_1_082392200 ((int)277) /* FIX(1.082392200) */
-#define FIX_1_414213562 ((int)362) /* FIX(1.414213562) */
-#define FIX_1_847759065 ((int)473) /* FIX(1.847759065) */
-#define FIX_2_613125930 ((int)669) /* FIX(2.613125930) */
-
-#define MULTIPLY(var, cons) ((int)((var) * (cons)) >> 8)
-
- int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- int tmp10, tmp11, tmp12, tmp13;
- int z5, z10, z11, z12, z13;
- int workspace[64]; /* buffers data between passes */
-
- short *inptr = coef;
- long *quantptr;
- int *wsptr = workspace;
- unsigned char *outptr;
- unsigned char *rLimit = rlimitTable + 128;
- int ctr, dcval, dctsize = 8;
-
- quantptr = &qt[nBlock][0];
-
- // Pass 1: process columns from input (inptr), store into work
- // array(wsptr)
-
- for (ctr = 8; ctr > 0; ctr--)
- {
- /* Due to quantization, we will usually find that many of the input
- * coefficients are zero, especially the AC terms. We can exploit
- * this by short-circuiting the IDCT calculation for any column in
- * which all the AC terms are zero. In that case each output is
- * equal to the DC coefficient (with scale factor as needed). With
- * typical images and quantization tables, half or more of the
- * column DCT calculations can be simplified this way.
- */
-
- if ((inptr[dctsize * 1] | inptr[dctsize * 2] | inptr[dctsize * 3] |
- inptr[dctsize * 4] | inptr[dctsize * 5] | inptr[dctsize * 6] |
- inptr[dctsize * 7]) == 0)
- {
- /* AC terms all zero */
- dcval = static_cast<int>(
- (inptr[dctsize * 0] * quantptr[dctsize * 0]) >> 16);
-
- wsptr[dctsize * 0] = dcval;
- wsptr[dctsize * 1] = dcval;
- wsptr[dctsize * 2] = dcval;
- wsptr[dctsize * 3] = dcval;
- wsptr[dctsize * 4] = dcval;
- wsptr[dctsize * 5] = dcval;
- wsptr[dctsize * 6] = dcval;
- wsptr[dctsize * 7] = dcval;
-
- inptr++; /* advance pointers to next column */
- quantptr++;
- wsptr++;
- continue;
- }
-
- /* Even part */
-
- tmp0 = (inptr[dctsize * 0] * quantptr[dctsize * 0]) >> 16;
- tmp1 = (inptr[dctsize * 2] * quantptr[dctsize * 2]) >> 16;
- tmp2 = (inptr[dctsize * 4] * quantptr[dctsize * 4]) >> 16;
- tmp3 = (inptr[dctsize * 6] * quantptr[dctsize * 6]) >> 16;
-
- tmp10 = tmp0 + tmp2; /* phase 3 */
- tmp11 = tmp0 - tmp2;
-
- tmp13 = tmp1 + tmp3; /* phases 5-3 */
- tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
-
- tmp0 = tmp10 + tmp13; /* phase 2 */
- tmp3 = tmp10 - tmp13;
- tmp1 = tmp11 + tmp12;
- tmp2 = tmp11 - tmp12;
-
- /* Odd part */
-
- tmp4 = (inptr[dctsize * 1] * quantptr[dctsize * 1]) >> 16;
- tmp5 = (inptr[dctsize * 3] * quantptr[dctsize * 3]) >> 16;
- tmp6 = (inptr[dctsize * 5] * quantptr[dctsize * 5]) >> 16;
- tmp7 = (inptr[dctsize * 7] * quantptr[dctsize * 7]) >> 16;
-
- z13 = tmp6 + tmp5; /* phase 6 */
- z10 = tmp6 - tmp5;
- z11 = tmp4 + tmp7;
- z12 = tmp4 - tmp7;
-
- tmp7 = z11 + z13; /* phase 5 */
- tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
-
- z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
- tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
- tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
-
- tmp6 = tmp12 - tmp7; /* phase 2 */
- tmp5 = tmp11 - tmp6;
- tmp4 = tmp10 + tmp5;
-
- wsptr[dctsize * 0] = (tmp0 + tmp7);
- wsptr[dctsize * 7] = (tmp0 - tmp7);
- wsptr[dctsize * 1] = (tmp1 + tmp6);
- wsptr[dctsize * 6] = (tmp1 - tmp6);
- wsptr[dctsize * 2] = (tmp2 + tmp5);
- wsptr[dctsize * 5] = (tmp2 - tmp5);
- wsptr[dctsize * 4] = (tmp3 + tmp4);
- wsptr[dctsize * 3] = (tmp3 - tmp4);
-
- inptr++; /* advance pointers to next column */
- quantptr++;
- wsptr++;
- }
-
-/* Pass 2: process rows from work array, store into output array. */
-/* Note that we must descale the results by a factor of 8 == 2**3, */
-/* and also undo the PASS1_BITS scaling. */
-
-//#define RANGE_MASK 1023; //2 bits wider than legal samples
-#define PASS1_BITS 0
-#define IDESCALE(x, n) ((int)((x) >> (n)))
-
- wsptr = workspace;
- for (ctr = 0; ctr < dctsize; ctr++)
- {
- outptr = data + ctr * 8;
-
- /* Rows of zeroes can be exploited in the same way as we did with
- * columns. However, the column calculation has created many nonzero
- * AC terms, so the simplification applies less often (typically 5%
- * to 10% of the time). On machines with very fast multiplication,
- * it's possible that the test takes more time than it's worth. In
- * that case this section may be commented out.
- */
- /* Even part */
-
- tmp10 = (wsptr[0] + wsptr[4]);
- tmp11 = (wsptr[0] - wsptr[4]);
-
- tmp13 = (wsptr[2] + wsptr[6]);
- tmp12 = MULTIPLY((int)wsptr[2] - (int)wsptr[6], FIX_1_414213562) -
- tmp13;
-
- tmp0 = tmp10 + tmp13;
- tmp3 = tmp10 - tmp13;
- tmp1 = tmp11 + tmp12;
- tmp2 = tmp11 - tmp12;
-
- /* Odd part */
-
- z13 = wsptr[5] + wsptr[3];
- z10 = wsptr[5] - wsptr[3];
- z11 = wsptr[1] + wsptr[7];
- z12 = wsptr[1] - wsptr[7];
-
- tmp7 = z11 + z13; /* phase 5 */
- tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
-
- z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
- tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
- tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
-
- tmp6 = tmp12 - tmp7; /* phase 2 */
- tmp5 = tmp11 - tmp6;
- tmp4 = tmp10 + tmp5;
-
- /* Final output stage: scale down by a factor of 8 and range-limit
- */
-
- outptr[0] =
- rLimit[IDESCALE((tmp0 + tmp7), (PASS1_BITS + 3)) & 1023L];
- outptr[7] =
- rLimit[IDESCALE((tmp0 - tmp7), (PASS1_BITS + 3)) & 1023L];
- outptr[1] =
- rLimit[IDESCALE((tmp1 + tmp6), (PASS1_BITS + 3)) & 1023L];
- outptr[6] =
- rLimit[IDESCALE((tmp1 - tmp6), (PASS1_BITS + 3)) & 1023L];
- outptr[2] =
- rLimit[IDESCALE((tmp2 + tmp5), (PASS1_BITS + 3)) & 1023L];
- outptr[5] =
- rLimit[IDESCALE((tmp2 - tmp5), (PASS1_BITS + 3)) & 1023L];
- outptr[4] =
- rLimit[IDESCALE((tmp3 + tmp4), (PASS1_BITS + 3)) & 1023L];
- outptr[3] =
- rLimit[IDESCALE((tmp3 - tmp4), (PASS1_BITS + 3)) & 1023L];
-
- wsptr += dctsize; /* advance pointer to next row */
- }
- }
- void yuvToRgb(
- int txb, int tyb,
- unsigned char
- *pYCbCr, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
- struct RGB *pYUV, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
- unsigned char
- *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
- )
- {
- int i, j, pos, m, n;
- unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
- int y;
- struct RGB *pByte;
- int nBlocksInMcu = 6;
- unsigned int pixelX, pixelY;
-
- pByte = reinterpret_cast<struct RGB *>(pBgr);
- if (yuvmode == YuvMode::YUV444)
- {
- py = pYCbCr;
- pcb = pYCbCr + 64;
- pcr = pcb + 64;
-
- pixelX = txb * 8;
- pixelY = tyb * 8;
- pos = (pixelY * width) + pixelX;
-
- for (j = 0; j < 8; j++)
- {
- for (i = 0; i < 8; i++)
- {
- m = ((j << 3) + i);
- y = py[m];
- cb = pcb[m];
- cr = pcr[m];
- n = pos + i;
- // For 2Pass. Save the YUV value
- pYUV[n].b = cb;
- pYUV[n].g = y;
- pYUV[n].r = cr;
- pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
- pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
- pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
- }
- pos += width;
- }
- }
- else
- {
- for (i = 0; i < nBlocksInMcu - 2; i++)
- {
- py420[i] = pYCbCr + i * 64;
- }
- pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
- pcr = pcb + 64;
-
- pixelX = txb * 16;
- pixelY = tyb * 16;
- pos = (pixelY * width) + pixelX;
-
- for (j = 0; j < 16; j++)
- {
- for (i = 0; i < 16; i++)
- {
- // block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
- y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
- m = ((j >> 1) << 3) + (i >> 1);
- cb = pcb[m];
- cr = pcr[m];
- n = pos + i;
- pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
- pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
- pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
- }
- pos += width;
- }
- }
- }
- void yuvToBuffer(
- int txb, int tyb,
- unsigned char
- *pYCbCr, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
- struct RGB
- *pYUV, // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
- unsigned char
- *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
- )
- {
- int i, j, pos, m, n;
- unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
- int y;
- struct RGB *pByte;
- int nBlocksInMcu = 6;
- unsigned int pixelX, pixelY;
-
- pByte = reinterpret_cast<struct RGB *>(pBgr);
- if (yuvmode == YuvMode::YUV444)
- {
- py = pYCbCr;
- pcb = pYCbCr + 64;
- pcr = pcb + 64;
-
- pixelX = txb * 8;
- pixelY = tyb * 8;
- pos = (pixelY * width) + pixelX;
-
- for (j = 0; j < 8; j++)
- {
- for (i = 0; i < 8; i++)
- {
- m = ((j << 3) + i);
- n = pos + i;
- y = pYUV[n].g + (py[m] - 128);
- cb = pYUV[n].b + (pcb[m] - 128);
- cr = pYUV[n].r + (pcr[m] - 128);
- pYUV[n].b = cb;
- pYUV[n].g = y;
- pYUV[n].r = cr;
- pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
- pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
- pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
- }
- pos += width;
- }
- }
- else
- {
- for (i = 0; i < nBlocksInMcu - 2; i++)
- {
- py420[i] = pYCbCr + i * 64;
- }
- pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
- pcr = pcb + 64;
-
- pixelX = txb * 16;
- pixelY = tyb * 16;
- pos = (pixelY * width) + pixelX;
-
- for (j = 0; j < 16; j++)
- {
- for (i = 0; i < 16; i++)
- {
- // block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
- y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
- m = ((j >> 1) << 3) + (i >> 1);
- cb = pcb[m];
- cr = pcr[m];
- n = pos + i;
- pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
- pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
- pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
- }
- pos += width;
- }
- }
- }
- void decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection)
- {
- unsigned char *ptr;
- unsigned char byTileYuv[768] = {};
-
- memset(dctCoeff, 0, 384 * 2);
- ptr = byTileYuv;
- processHuffmanDataUnit(ydcNr, yacNr, &dcy, 0);
- idctTransform(dctCoeff, ptr, QT_TableSelection);
- ptr += 64;
-
- if (yuvmode == YuvMode::YUV420)
- {
- processHuffmanDataUnit(ydcNr, yacNr, &dcy, 64);
- idctTransform(dctCoeff + 64, ptr, QT_TableSelection);
- ptr += 64;
-
- processHuffmanDataUnit(ydcNr, yacNr, &dcy, 128);
- idctTransform(dctCoeff + 128, ptr, QT_TableSelection);
- ptr += 64;
-
- processHuffmanDataUnit(ydcNr, yacNr, &dcy, 192);
- idctTransform(dctCoeff + 192, ptr, QT_TableSelection);
- ptr += 64;
-
- processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 256);
- idctTransform(dctCoeff + 256, ptr, QT_TableSelection + 1);
- ptr += 64;
-
- processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 320);
- idctTransform(dctCoeff + 320, ptr, QT_TableSelection + 1);
- }
- else
- {
- processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 64);
- idctTransform(dctCoeff + 64, ptr, QT_TableSelection + 1);
- ptr += 64;
-
- processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 128);
- idctTransform(dctCoeff + 128, ptr, QT_TableSelection + 1);
- }
-
- // yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
- // yuvBuffer for YUV record
- yuvToRgb(txb, tyb, byTileYuv, yuvBuffer.data(),
- reinterpret_cast<unsigned char *>(outBuf));
- }
-
- void decompress2Pass(int txb, int tyb, char *outBuf,
- uint8_t QT_TableSelection)
- {
- unsigned char *ptr;
- unsigned char byTileYuv[768];
- memset(dctCoeff, 0, 384 * 2);
-
- ptr = byTileYuv;
- processHuffmanDataUnit(ydcNr, yacNr, &dcy, 0);
- idctTransform(dctCoeff, ptr, QT_TableSelection);
- ptr += 64;
-
- processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 64);
- idctTransform(dctCoeff + 64, ptr, QT_TableSelection + 1);
- ptr += 64;
-
- processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 128);
- idctTransform(dctCoeff + 128, ptr, QT_TableSelection + 1);
-
- yuvToBuffer(txb, tyb, byTileYuv, yuvBuffer.data(),
- reinterpret_cast<unsigned char *>(outBuf));
- // yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
- }
-
- void vqDecompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection,
- struct ColorCache *VQ)
- {
- unsigned char *ptr, i;
- unsigned char byTileYuv[192];
- int data;
-
- ptr = byTileYuv;
- if (VQ->bitMapBits == 0)
- {
- for (i = 0; i < 64; i++)
- {
- ptr[0] = (VQ->color[VQ->index[0]] & 0xFF0000) >> 16;
- ptr[64] = (VQ->color[VQ->index[0]] & 0x00FF00) >> 8;
- ptr[128] = VQ->color[VQ->index[0]] & 0x0000FF;
- ptr += 1;
- }
- }
- else
- {
- for (i = 0; i < 64; i++)
- {
- data = static_cast<int>(lookKbits(VQ->bitMapBits));
- ptr[0] = (VQ->color[VQ->index[data]] & 0xFF0000) >> 16;
- ptr[64] = (VQ->color[VQ->index[data]] & 0x00FF00) >> 8;
- ptr[128] = VQ->color[VQ->index[data]] & 0x0000FF;
- ptr += 1;
- skipKbits(VQ->bitMapBits);
- }
- }
- // yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
- yuvToRgb(txb, tyb, byTileYuv, yuvBuffer.data(),
- reinterpret_cast<unsigned char *>(outBuf));
- }
-
- void moveBlockIndex()
- {
- if (yuvmode == YuvMode::YUV444)
- {
- txb++;
- if (txb >= static_cast<int>(width / 8))
- {
- tyb++;
- if (tyb >= static_cast<int>(height / 8))
- {
- tyb = 0;
- }
- txb = 0;
- }
- }
- else
- {
- txb++;
- if (txb >= static_cast<int>(width / 16))
- {
- tyb++;
- if (tyb >= static_cast<int>(height / 16))
- {
- tyb = 0;
- }
- txb = 0;
- }
- }
- }
-
- void initColorTable()
- {
- int i, x;
- int nScale = 1L << 16; // equal to power(2,16)
- int nHalf = nScale >> 1;
-
-#define FIX(x) ((int)((x)*nScale + 0.5))
-
- /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
- /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
- /* Cr=>r value is nearest int to 1.597656 * x */
- /* Cb=>b value is nearest int to 2.015625 * x */
- /* Cr=>g value is scaled-up -0.8125 * x */
- /* Cb=>g value is scaled-up -0.390625 * x */
- for (i = 0, x = -128; i < 256; i++, x++)
- {
- mCrToR[i] = (FIX(1.597656) * x + nHalf) >> 16;
- mCbToB[i] = (FIX(2.015625) * x + nHalf) >> 16;
- mCrToG[i] = (-FIX(0.8125) * x + nHalf) >> 16;
- mCbToG[i] = (-FIX(0.390625) * x + nHalf) >> 16;
- }
- for (i = 0, x = -16; i < 256; i++, x++)
- {
- mY[i] = (FIX(1.164) * x + nHalf) >> 16;
- }
- // For color Text Enchance Y Re-map. Recommend to disable in default
- /*
- for (i = 0; i <
- (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate); i++) { temp =
- (double)i / VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate; temp1
- = 1.0 / VideoEngineInfo->INFData.Gamma1Parameter; mY[i] =
- (BYTE)(VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate * pow (temp,
- temp1));
- if (mY[i] > 255) mY[i] = 255;
- }
- for (i = (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate); i <
- 256; i++) { mY[i] =
- (BYTE)((VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) + (256 -
- VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) * ( pow((double)((i
- - VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) / (256 -
- (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate))), (1.0 /
- VideoEngineInfo->INFData.Gamma2Parameter)) ));
- if (mY[i] > 255) mY[i] = 255;
- }
- */
- }
- void loadHuffmanTable(HuffmanTable *HT, const unsigned char *nrcode,
- const unsigned char *value,
- const unsigned short int *Huff_code)
- {
- unsigned char k, j, i;
- unsigned int code, codeIndex;
-
- for (j = 1; j <= 16; j++)
- {
- HT->length[j] = nrcode[j];
- }
- for (i = 0, k = 1; k <= 16; k++)
- {
- for (j = 0; j < HT->length[k]; j++)
- {
- HT->v[wordHiLo(k, j)] = value[i];
- i++;
- }
- }
-
- code = 0;
- for (k = 1; k <= 16; k++)
- {
- HT->minorCode[k] = static_cast<unsigned short int>(code);
- for (j = 1; j <= HT->length[k]; j++)
- {
- code++;
- }
- HT->majorCode[k] = static_cast<unsigned short int>(code - 1);
- code *= 2;
- if (HT->length[k] == 0)
- {
- HT->minorCode[k] = 0xFFFF;
- HT->majorCode[k] = 0;
- }
- }
-
- HT->len[0] = 2;
- i = 2;
-
- for (codeIndex = 1; codeIndex < 65535; codeIndex++)
- {
- if (codeIndex < Huff_code[i])
- {
- HT->len[codeIndex] =
- static_cast<unsigned char>(Huff_code[i + 1]);
- }
- else
- {
- i = i + 2;
- HT->len[codeIndex] =
- static_cast<unsigned char>(Huff_code[i + 1]);
- }
- }
- }
- void initJpgTable()
- {
- initColorTable();
- prepareRangeLimitTable();
- loadHuffmanTable(&htdc[0], stdDcLuminanceNrcodes, stdDcLuminanceValues,
- dcLuminanceHuffmancode);
- loadHuffmanTable(&htac[0], stdAcLuminanceNrcodes, stdAcLuminanceValues,
- acLuminanceHuffmancode);
- loadHuffmanTable(&htdc[1], stdDcChrominanceNrcodes,
- stdDcChrominanceValues, dcChrominanceHuffmancode);
- loadHuffmanTable(&htac[1], stdAcChrominanceNrcodes,
- stdAcChrominanceValues, acChrominanceHuffmancode);
- }
-
- void prepareRangeLimitTable()
- /* Allocate and fill in the sample_range_limit table */
- {
- int j;
- rlimitTable = reinterpret_cast<unsigned char *>(malloc(5 * 256L + 128));
- /* First segment of "simple" table: limit[x] = 0 for x < 0 */
- memset((void *)rlimitTable, 0, 256);
- rlimitTable += 256; /* allow negative subscripts of simple table */
- /* Main part of "simple" table: limit[x] = x */
- for (j = 0; j < 256; j++)
- {
- rlimitTable[j] = j;
- }
- /* End of simple table, rest of first half of post-IDCT table */
- for (j = 256; j < 640; j++)
- {
- rlimitTable[j] = 255;
- }
-
- /* Second half of post-IDCT table */
- memset((void *)(rlimitTable + 640), 0, 384);
- for (j = 0; j < 128; j++)
- {
- rlimitTable[j + 1024] = j;
- }
- }
-
- inline unsigned short int wordHiLo(uint8_t byte_high, uint8_t byte_low)
- {
- return (byte_high << 8) + byte_low;
- }
-
- // river
- void processHuffmanDataUnit(uint8_t DC_nr, uint8_t AC_nr,
- signed short int *previous_DC,
- unsigned short int position)
- {
- uint8_t nr = 0;
- uint8_t k;
- unsigned short int tmpHcode;
- uint8_t sizeVal, count0;
- unsigned short int *minCode;
- uint8_t *huffValues;
- uint8_t byteTemp;
-
- minCode = htdc[DC_nr].minorCode;
- // maj_code=htdc[DC_nr].majorCode;
- huffValues = htdc[DC_nr].v;
-
- // DC
- k = htdc[DC_nr].len[static_cast<unsigned short int>(codebuf >> 16)];
- // river
- // tmp_Hcode=lookKbits(k);
- tmpHcode = static_cast<unsigned short int>(codebuf >> (32 - k));
- skipKbits(k);
- sizeVal = huffValues[wordHiLo(
- k, static_cast<uint8_t>(tmpHcode - minCode[k]))];
- if (sizeVal == 0)
- {
- dctCoeff[position + 0] = *previous_DC;
- }
- else
- {
- dctCoeff[position + 0] = *previous_DC + getKbits(sizeVal);
- *previous_DC = dctCoeff[position + 0];
- }
-
- // Second, AC coefficient decoding
- minCode = htac[AC_nr].minorCode;
- // maj_code=htac[AC_nr].majorCode;
- huffValues = htac[AC_nr].v;
-
- nr = 1; // AC coefficient
- do
- {
- k = htac[AC_nr].len[static_cast<unsigned short int>(codebuf >> 16)];
- tmpHcode = static_cast<unsigned short int>(codebuf >> (32 - k));
- skipKbits(k);
-
- byteTemp = huffValues[wordHiLo(
- k, static_cast<uint8_t>(tmpHcode - minCode[k]))];
- sizeVal = byteTemp & 0xF;
- count0 = byteTemp >> 4;
- if (sizeVal == 0)
- {
- if (count0 != 0xF)
- {
- break;
- }
- nr += 16;
- }
- else
- {
- nr += count0; // skip count_0 zeroes
- dctCoeff[position + dezigzag[nr++]] = getKbits(sizeVal);
- }
- } while (nr < 64);
- }
-
- unsigned short int lookKbits(uint8_t k)
- {
- unsigned short int revcode;
-
- revcode = static_cast<unsigned short int>(codebuf >> (32 - k));
-
- return (revcode);
- }
-
- void skipKbits(uint8_t k)
- {
- unsigned long readbuf;
-
- if ((newbits - k) <= 0)
- {
- readbuf = buffer[bufferIndex];
- bufferIndex++;
- codebuf = (codebuf << k) |
- ((newbuf | (readbuf >> (newbits))) >> (32 - k));
- newbuf = readbuf << (k - newbits);
- newbits = 32 + newbits - k;
- }
- else
- {
- codebuf = (codebuf << k) | (newbuf >> (32 - k));
- newbuf = newbuf << k;
- newbits -= k;
- }
- }
-
- signed short int getKbits(uint8_t k)
- {
- signed short int signedWordvalue;
-
- // river
- // signed_wordvalue=lookKbits(k);
- signedWordvalue = static_cast<unsigned short int>(codebuf >> (32 - k));
- if (((1L << (k - 1)) & signedWordvalue) == 0)
- {
- // neg_pow2 was previously defined as the below. It seemed silly to
- // keep a table of values around for something THat's relatively
- // easy to compute, so it was replaced with the appropriate math
- // signed_wordvalue = signed_wordvalue - (0xFFFF >> (16 - k));
- std::array<signed short int, 17> negPow2 = {
- 0, -1, -3, -7, -15, -31, -63, -127,
- -255, -511, -1023, -2047, -4095, -8191, -16383, -32767};
-
- signedWordvalue = signedWordvalue + negPow2[k];
- }
- skipKbits(k);
- return signedWordvalue;
- }
- int initJpgDecoding()
- {
- bytePos = 0;
- loadQuantTable(qt[0]);
- loadQuantTableCb(qt[1]);
- // Note: Added for Dual-JPEG
- loadAdvanceQuantTable(qt[2]);
- loadAdvanceQuantTableCb(qt[3]);
- return 1;
- }
-
- void setQuantTable(const uint8_t *basic_table, uint8_t scale_factor,
- std::array<uint8_t, 64> &newtable)
- // Set quantization table and zigzag reorder it
- {
- uint8_t i;
- long temp;
- for (i = 0; i < 64; i++)
- {
- temp = (static_cast<long>(basic_table[i] * 16) / scale_factor);
- /* limit the values to the valid range */
- if (temp <= 0L)
- {
- temp = 1L;
- }
- if (temp > 255L)
- {
- temp = 255L; /* limit to baseline range if requested */
- }
- newtable[zigzag[i]] = static_cast<uint8_t>(temp);
- }
- }
-
- void updatereadbuf(uint32_t *codebuf, uint32_t *newbuf, int walks,
- int *newbits, std::vector<uint32_t> &buffer)
- {
- unsigned long readbuf;
-
- if ((*newbits - walks) <= 0)
- {
- readbuf = buffer[bufferIndex];
- bufferIndex++;
- *codebuf = (*codebuf << walks) |
- ((*newbuf | (readbuf >> (*newbits))) >> (32 - walks));
- *newbuf = readbuf << (walks - *newbits);
- *newbits = 32 + *newbits - walks;
- }
- else
- {
- *codebuf = (*codebuf << walks) | (*newbuf >> (32 - walks));
- *newbuf = *newbuf << walks;
- *newbits -= walks;
- }
- }
-
- uint32_t decode(std::vector<uint32_t> &bufferVector, unsigned long width,
- unsigned long height, YuvMode yuvmode_in, int ySelector,
- int uvSelector)
- {
- ColorCache decodeColor;
- if (width != userWidth || height != userHeight ||
- yuvmode_in != yuvmode || ySelector != ySelector ||
- uvSelector != uvSelector)
- {
- yuvmode = yuvmode_in;
- ySelector = ySelector; // 0-7
- uvSelector = uvSelector; // 0-7
- userHeight = height;
- userWidth = width;
- width = width;
- height = height;
-
- // TODO(ed) Magic number section. Document appropriately
- advanceSelector = 0; // 0-7
- mapping = 0; // 0 or 1
-
- if (yuvmode == YuvMode::YUV420)
- {
- if ((width % 16) != 0u)
- {
- width = width + 16 - (width % 16);
- }
- if ((height % 16) != 0u)
- {
- height = height + 16 - (height % 16);
- }
- }
- else
- {
- if ((width % 8) != 0u)
- {
- width = width + 8 - (width % 8);
- }
- if ((height % 8) != 0u)
- {
- height = height + 8 - (height % 8);
- }
- }
-
- initJpgDecoding();
- }
- // TODO(ed) cleanup cruft
- buffer = bufferVector.data();
-
- codebuf = bufferVector[0];
- newbuf = bufferVector[1];
- bufferIndex = 2;
-
- txb = tyb = 0;
- newbits = 32;
- dcy = dcCb = dcCr = 0;
-
- static const uint32_t vqHeaderMask = 0x01;
- static const uint32_t vqNoUpdateHeader = 0x00;
- static const uint32_t vqUpdateHeader = 0x01;
- static const int vqNoUpdateLength = 0x03;
- static const int vqUpdateLength = 0x1B;
- static const uint32_t vqIndexMask = 0x03;
- static const uint32_t vqColorMask = 0xFFFFFF;
-
- static const int blockAsT2100StartLength = 0x04;
- static const int blockAsT2100SkipLength = 20; // S:1 H:3 X:8 Y:8
-
- do
- {
- auto blockHeader = static_cast<JpgBlock>((codebuf >> 28) & 0xFF);
- switch (blockHeader)
- {
- case JpgBlock::JPEG_NO_SKIP_CODE:
- updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength,
- &newbits, bufferVector);
- decompress(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()), 0);
- break;
- case JpgBlock::FRAME_END_CODE:
- return 0;
- break;
- case JpgBlock::JPEG_SKIP_CODE:
-
- txb = (codebuf & 0x0FF00000) >> 20;
- tyb = (codebuf & 0x0FF000) >> 12;
-
- updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
- &newbits, bufferVector);
- decompress(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()), 0);
- break;
- case JpgBlock::VQ_NO_SKIP_1_COLOR_CODE:
- updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength,
- &newbits, bufferVector);
- decodeColor.bitMapBits = 0;
-
- for (int i = 0; i < 1; i++)
- {
- decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
- if (((codebuf >> 31) & vqHeaderMask) ==
- vqNoUpdateHeader)
- {
- updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
- &newbits, bufferVector);
- }
- else
- {
- decodeColor.color[decodeColor.index[i]] =
- ((codebuf >> 5) & vqColorMask);
- updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
- &newbits, bufferVector);
- }
- }
- vqDecompress(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()), 0,
- &decodeColor);
- break;
- case JpgBlock::VQ_SKIP_1_COLOR_CODE:
- txb = (codebuf & 0x0FF00000) >> 20;
- tyb = (codebuf & 0x0FF000) >> 12;
-
- updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
- &newbits, bufferVector);
- decodeColor.bitMapBits = 0;
-
- for (int i = 0; i < 1; i++)
- {
- decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
- if (((codebuf >> 31) & vqHeaderMask) ==
- vqNoUpdateHeader)
- {
- updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
- &newbits, bufferVector);
- }
- else
- {
- decodeColor.color[decodeColor.index[i]] =
- ((codebuf >> 5) & vqColorMask);
- updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
- &newbits, bufferVector);
- }
- }
- vqDecompress(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()), 0,
- &decodeColor);
- break;
-
- case JpgBlock::VQ_NO_SKIP_2_COLOR_CODE:
- updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength,
- &newbits, bufferVector);
- decodeColor.bitMapBits = 1;
-
- for (int i = 0; i < 2; i++)
- {
- decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
- if (((codebuf >> 31) & vqHeaderMask) ==
- vqNoUpdateHeader)
- {
- updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
- &newbits, bufferVector);
- }
- else
- {
- decodeColor.color[decodeColor.index[i]] =
- ((codebuf >> 5) & vqColorMask);
- updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
- &newbits, bufferVector);
- }
- }
- vqDecompress(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()), 0,
- &decodeColor);
- break;
- case JpgBlock::VQ_SKIP_2_COLOR_CODE:
- txb = (codebuf & 0x0FF00000) >> 20;
- tyb = (codebuf & 0x0FF000) >> 12;
-
- updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
- &newbits, bufferVector);
- decodeColor.bitMapBits = 1;
-
- for (int i = 0; i < 2; i++)
- {
- decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
- if (((codebuf >> 31) & vqHeaderMask) ==
- vqNoUpdateHeader)
- {
- updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
- &newbits, bufferVector);
- }
- else
- {
- decodeColor.color[decodeColor.index[i]] =
- ((codebuf >> 5) & vqColorMask);
- updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
- &newbits, bufferVector);
- }
- }
- vqDecompress(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()), 0,
- &decodeColor);
-
- break;
- case JpgBlock::VQ_NO_SKIP_4_COLOR_CODE:
- updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength,
- &newbits, bufferVector);
- decodeColor.bitMapBits = 2;
-
- for (unsigned char &i : decodeColor.index)
- {
- i = ((codebuf >> 29) & vqIndexMask);
- if (((codebuf >> 31) & vqHeaderMask) ==
- vqNoUpdateHeader)
- {
- updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
- &newbits, bufferVector);
- }
- else
- {
- decodeColor.color[i] =
- ((codebuf >> 5) & vqColorMask);
- updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
- &newbits, bufferVector);
- }
- }
- vqDecompress(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()), 0,
- &decodeColor);
-
- break;
-
- case JpgBlock::VQ_SKIP_4_COLOR_CODE:
- txb = (codebuf & 0x0FF00000) >> 20;
- tyb = (codebuf & 0x0FF000) >> 12;
-
- updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
- &newbits, bufferVector);
- decodeColor.bitMapBits = 2;
-
- for (unsigned char &i : decodeColor.index)
- {
- i = ((codebuf >> 29) & vqIndexMask);
- if (((codebuf >> 31) & vqHeaderMask) ==
- vqNoUpdateHeader)
- {
- updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
- &newbits, bufferVector);
- }
- else
- {
- decodeColor.color[i] =
- ((codebuf >> 5) & vqColorMask);
- updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
- &newbits, bufferVector);
- }
- }
- vqDecompress(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()), 0,
- &decodeColor);
-
- break;
- case JpgBlock::JPEG_SKIP_PASS2_CODE:
- txb = (codebuf & 0x0FF00000) >> 20;
- tyb = (codebuf & 0x0FF000) >> 12;
-
- updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
- &newbits, bufferVector);
- decompress2Pass(txb, tyb,
- reinterpret_cast<char *>(outBuffer.data()),
- 2);
-
- break;
- default:
- // TODO(ed) propogate errors upstream
- return -1;
- break;
- }
- moveBlockIndex();
-
- } while (bufferIndex <= bufferVector.size());
-
- return -1;
- }
-
-#ifdef cimg_version
- void dump_to_bitmap_file()
- {
- cimg_library::CImg<unsigned char> image(width, height, 1, 3);
- for (int y = 0; y < width; y++)
- {
- for (int x = 0; x < height; x++)
- {
- auto pixel = outBuffer[x + (y * width)];
- image(x, y, 0) = pixel.r;
- image(x, y, 1) = pixel.g;
- image(x, y, 2) = pixel.b;
- }
- }
- image.save("/tmp/file2.bmp");
- }
-#endif
-
- private:
- YuvMode yuvmode{};
- // width and height are the modes your display used
- unsigned long width{};
- unsigned long height{};
- unsigned long userWidth{};
- unsigned long userHeight{};
- unsigned char ySelector{};
- int scalefactor;
- int scalefactoruv;
- int advancescalefactor;
- int advancescalefactoruv;
- int mapping{};
- unsigned char uvSelector{};
- unsigned char advanceSelector{};
- int bytePos{}; // current byte position
-
- // quantization tables, no more than 4 quantization tables
- std::array<std::array<long, 64>, 4> qt{};
-
- // DC huffman tables , no more than 4 (0..3)
- std::array<HuffmanTable, 4> htdc{};
- // AC huffman tables (0..3)
- std::array<HuffmanTable, 4> htac{};
- std::array<int, 256> mCrToR{};
- std::array<int, 256> mCbToB{};
- std::array<int, 256> mCrToG{};
- std::array<int, 256> mCbToG{};
- std::array<int, 256> mY{};
- unsigned long bufferIndex{};
- uint32_t codebuf{}, newbuf{}, readbuf{};
- const unsigned char *stdLuminanceQt{};
- const uint8_t *stdChrominanceQt{};
-
- signed short int dcy{}, dcCb{}, dcCr{}; // Coeficientii DC pentru Y,Cb,Cr
- signed short int dctCoeff[384]{};
- // std::vector<signed short int> dctCoeff; // Current DCT_coefficients
- // quantization table number for Y, Cb, Cr
- uint8_t yqNr = 0, cbQNr = 1, crQNr = 1;
- // DC Huffman table number for Y,Cb, Cr
- uint8_t ydcNr = 0, cbDcNr = 1, crDcNr = 1;
- // AC Huffman table number for Y,Cb, Cr
- uint8_t yacNr = 0, cbAcNr = 1, crAcNr = 1;
- int txb = 0;
- int tyb = 0;
- int newbits{};
- uint8_t *rlimitTable{};
- std::vector<RGB> yuvBuffer;
- // TODO(ed) this shouldn't exist. It is cruft that needs cleaning up
- uint32_t *buffer{};
-
- public:
- std::vector<RGB> outBuffer;
-};
-} // namespace ast_video \ No newline at end of file
diff --git a/include/kvm_websocket.hpp b/include/kvm_websocket.hpp
new file mode 100644
index 0000000000..aa2eaecc32
--- /dev/null
+++ b/include/kvm_websocket.hpp
@@ -0,0 +1,173 @@
+#pragma once
+#include <crow/app.h>
+#include <crow/websocket.h>
+#include <sys/socket.h>
+
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <webserver_common.hpp>
+
+namespace crow
+{
+namespace obmc_kvm
+{
+
+static std::unique_ptr<boost::asio::ip::tcp::socket> hostSocket;
+
+// TODO(ed) validate that these buffer sizes are sane
+static boost::beast::flat_static_buffer<1024U * 50U> outputBuffer;
+static boost::beast::flat_static_buffer<1024U> inputBuffer;
+
+static crow::websocket::Connection* session = nullptr;
+
+static bool doingWrite = false;
+
+inline void doWrite()
+{
+ if (doingWrite)
+ {
+ BMCWEB_LOG_DEBUG << "Already writing. Bailing out";
+ return;
+ }
+ if (inputBuffer.size() == 0)
+ {
+ BMCWEB_LOG_DEBUG << "inputBuffer empty. Bailing out";
+ return;
+ }
+
+ doingWrite = true;
+ hostSocket->async_write_some(
+ inputBuffer.data(),
+ [](boost::beast::error_code ec, std::size_t bytes_written) {
+ BMCWEB_LOG_DEBUG << "Wrote " << bytes_written << "bytes";
+ doingWrite = false;
+ inputBuffer.consume(bytes_written);
+
+ if (session == nullptr)
+ {
+ return;
+ }
+ if (ec == boost::asio::error::eof)
+ {
+ session->close("KVM socket port closed");
+ return;
+ }
+ if (ec)
+ {
+ session->close("Error in reading to host port");
+ BMCWEB_LOG_ERROR << "Error in KVM socket write " << ec;
+ return;
+ }
+ doWrite();
+ });
+}
+
+inline void doRead();
+
+inline void readDone(const boost::system::error_code& ec, std::size_t bytesRead)
+{
+ outputBuffer.commit(bytesRead);
+ BMCWEB_LOG_DEBUG << "read done. Read " << bytesRead << " bytes";
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "Couldn't read from KVM socket port: " << ec;
+ if (session != nullptr)
+ {
+ session->close("Error in connecting to KVM port");
+ }
+ return;
+ }
+ if (session == nullptr)
+ {
+ return;
+ }
+
+ boost::beast::string_view payload(
+ static_cast<const char*>(outputBuffer.data().data()), bytesRead);
+ BMCWEB_LOG_DEBUG << "Sending payload size " << payload.size();
+ session->sendBinary(payload);
+ outputBuffer.consume(bytesRead);
+
+ doRead();
+}
+
+inline void doRead()
+{
+ std::size_t bytes = outputBuffer.capacity() - outputBuffer.size();
+ BMCWEB_LOG_DEBUG << "Reading " << bytes << " from kvm socket";
+ hostSocket->async_read_some(
+ outputBuffer.prepare(outputBuffer.capacity() - outputBuffer.size()),
+ readDone);
+}
+
+inline void connectHandler(const boost::system::error_code& ec)
+{
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "Couldn't connect to KVM socket port: " << ec;
+ if (session != nullptr)
+ {
+ session->close("Error in connecting to KVM port");
+ }
+ return;
+ }
+
+ doWrite();
+ doRead();
+}
+
+inline void requestRoutes(CrowApp& app)
+{
+ BMCWEB_ROUTE(app, "/kvm/0")
+ .websocket()
+ .onopen([](crow::websocket::Connection& conn) {
+ BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";
+
+ if (session != nullptr)
+ {
+ conn.close("User already connected");
+ return;
+ }
+
+ session = &conn;
+ if (hostSocket == nullptr)
+ {
+ boost::asio::ip::tcp::endpoint endpoint(
+ boost::asio::ip::address::from_string("127.0.0.1"), 5900);
+
+ hostSocket = std::make_unique<boost::asio::ip::tcp::socket>(
+ conn.get_io_context());
+ hostSocket->async_connect(endpoint, connectHandler);
+ }
+ })
+ .onclose(
+ [](crow::websocket::Connection& conn, const std::string& reason) {
+ session = nullptr;
+ hostSocket = nullptr;
+ inputBuffer.reset();
+ outputBuffer.reset();
+ })
+ .onmessage([](crow::websocket::Connection& conn,
+ const std::string& data, bool is_binary) {
+ if (data.length() > inputBuffer.capacity())
+ {
+ BMCWEB_LOG_ERROR << "Buffer overrun when writing "
+ << data.length() << " bytes";
+ conn.close("Buffer overrun");
+ return;
+ }
+
+ BMCWEB_LOG_DEBUG << "Read " << data.size()
+ << " bytes from websocket";
+ boost::asio::buffer_copy(inputBuffer.prepare(data.size()),
+ boost::asio::buffer(data));
+ BMCWEB_LOG_DEBUG << "commiting " << data.size()
+ << " bytes from websocket";
+ inputBuffer.commit(data.size());
+
+ BMCWEB_LOG_DEBUG << "inputbuffer size " << inputBuffer.size();
+ doWrite();
+ });
+}
+} // namespace obmc_kvm
+} // namespace crow
diff --git a/include/security_headers_middleware.hpp b/include/security_headers_middleware.hpp
index 5e8e7d9911..1ebc43ca7a 100644
--- a/include/security_headers_middleware.hpp
+++ b/include/security_headers_middleware.hpp
@@ -36,7 +36,12 @@ struct SecurityHeadersMiddleware
res.addHeader(bf::pragma, "no-cache");
res.addHeader(bf::cache_control, "no-Store,no-Cache");
- res.addHeader("Content-Security-Policy", "default-src 'self'");
+
+ // The KVM currently needs to load images from base64 encoded strings.
+ // img-src 'self' data: is used to allow that.
+ // https://stackoverflow.com/questions/18447970/content-security-policy-data-not-working-for-base64-images-in-chrome-28
+ res.addHeader("Content-Security-Policy",
+ "default-src 'self'; img-src 'self' data:");
res.addHeader("X-XSS-Protection", "1; "
"mode=block");
res.addHeader("X-Content-Type-Options", "nosniff");
diff --git a/include/web_kvm.hpp b/include/web_kvm.hpp
deleted file mode 100644
index 747a137b87..0000000000
--- a/include/web_kvm.hpp
+++ /dev/null
@@ -1,422 +0,0 @@
-#include <crow/app.h>
-
-#include <ast_jpeg_decoder.hpp>
-#include <ast_video_puller.hpp>
-#include <boost/endian/arithmetic.hpp>
-#include <string>
-
-namespace crow
-{
-namespace kvm
-{
-
-static const std::string rfb33VersionString = "RFB 003.003\n";
-static const std::string rfb37VersionString = "RFB 003.007\n";
-static const std::string rfb38VersionString = "RFB 003.008\n";
-
-enum class RfbAuthScheme : uint8_t
-{
- connection_failed = 0,
- no_authentication = 1,
- vnc_authentication = 2
-};
-
-struct PixelFormatStruct
-{
- boost::endian::big_uint8_t bitsPerPixel;
- boost::endian::big_uint8_t depth;
- boost::endian::big_uint8_t isBigEndian;
- boost::endian::big_uint8_t isTrueColor;
- boost::endian::big_uint16_t redMax;
- boost::endian::big_uint16_t greenMax;
- boost::endian::big_uint16_t blueMax;
- boost::endian::big_uint8_t redShift;
- boost::endian::big_uint8_t greenShift;
- boost::endian::big_uint8_t blueShift;
- boost::endian::big_uint8_t pad1;
- boost::endian::big_uint8_t pad2;
- boost::endian::big_uint8_t pad3;
-};
-
-struct ServerInitializationMsg
-{
- boost::endian::big_uint16_t framebufferWidth;
- boost::endian::big_uint16_t framebufferHeight;
- PixelFormatStruct pixelFormat;
- boost::endian::big_uint32_t nameLength;
-};
-
-enum class client_to_server_msg_type : uint8_t
-{
- set_pixel_format = 0,
- fix_color_map_entries = 1,
- set_encodings = 2,
- framebuffer_update_request = 3,
- key_event = 4,
- pointer_event = 5,
- client_cut_text = 6
-};
-
-enum class server_to_client_message_type : uint8_t
-{
- framebuffer_update = 0,
- set_color_map_entries = 1,
- bell_message = 2,
- server_cut_text = 3
-};
-
-struct SetPixelFormatMsg
-{
- boost::endian::big_uint8_t pad1;
- boost::endian::big_uint8_t pad2;
- boost::endian::big_uint8_t pad3;
- PixelFormatStruct pixelFormat;
-};
-
-struct FrameBufferUpdateReq
-{
- boost::endian::big_uint8_t incremental;
- boost::endian::big_uint16_t xPosition;
- boost::endian::big_uint16_t yPosition;
- boost::endian::big_uint16_t width;
- boost::endian::big_uint16_t height;
-};
-
-struct KeyEventMsg
-{
- boost::endian::big_uint8_t downFlag;
- boost::endian::big_uint8_t pad1;
- boost::endian::big_uint8_t pad2;
- boost::endian::big_uint32_t key;
-};
-
-struct PointerEventMsg
-{
- boost::endian::big_uint8_t buttonMask;
- boost::endian::big_uint16_t xPosition;
- boost::endian::big_uint16_t yPosition;
-};
-
-struct ClientCutTextMsg
-{
- std::vector<uint8_t> data;
-};
-
-enum class encoding_type : uint32_t
-{
- raw = 0x00,
- copy_rectangle = 0x01,
- rising_rectangle = 0x02,
- corre = 0x04,
- hextile = 0x05,
- zlib = 0x06,
- tight = 0x07,
- zlibhex = 0x08,
- ultra = 0x09,
- zrle = 0x10,
- zywrle = 0x011,
- cache_enable = 0xFFFF0001,
- xor_enable = 0xFFFF0006,
- server_state_ultranvc = 0xFFFF8000,
- enable_keepAlive = 0xFFFF8001,
- enableftp_protocol_version = 0xFFFF8002,
- tight_compress_level_0 = 0xFFFFFF00,
- tight_compress_level_9 = 0xFFFFFF09,
- x_cursor = 0xFFFFFF10,
- rich_cursor = 0xFFFFFF11,
- pointer_pos = 0xFFFFFF18,
- last_rect = 0xFFFFFF20,
- new_framebuffer_size = 0xFFFFFF21,
- tight_quality_level_0 = 0xFFFFFFE0,
- tight_quality_level_9 = 0xFFFFFFE9
-};
-
-struct FramebufferRectangle
-{
- boost::endian::big_uint16_t x{};
- boost::endian::big_uint16_t y{};
- boost::endian::big_uint16_t width{};
- boost::endian::big_uint16_t height{};
- boost::endian::big_uint32_t encoding{};
- std::vector<uint8_t> data;
-};
-
-struct FramebufferUpdateMsg
-{
- boost::endian::big_uint8_t messageType{};
- std::vector<FramebufferRectangle> rectangles;
-};
-
-inline std::string serialize(const FramebufferUpdateMsg& msg)
-{
- // calculate the size of the needed vector for serialization
- size_t vectorSize = 4;
- for (const auto& rect : msg.rectangles)
- {
- vectorSize += 12 + rect.data.size();
- }
-
- std::string serialized(vectorSize, 0);
-
- size_t i = 0;
- serialized[i++] = static_cast<char>(
- server_to_client_message_type::framebuffer_update); // Type
- serialized[i++] = 0; // Pad byte
- boost::endian::big_uint16_t numberOfRectangles = msg.rectangles.size();
- std::memcpy(&serialized[i], &numberOfRectangles,
- sizeof(numberOfRectangles));
- i += sizeof(numberOfRectangles);
-
- for (const auto& rect : msg.rectangles)
- {
- // copy the first part of the struct
- size_t bufferSize =
- sizeof(FramebufferRectangle) - sizeof(std::vector<uint8_t>);
- std::memcpy(&serialized[i], &rect, bufferSize);
- i += bufferSize;
-
- std::memcpy(&serialized[i], rect.data.data(), rect.data.size());
- i += rect.data.size();
- }
-
- return serialized;
-}
-
-enum class VncState
-{
- UNSTARTED,
- AWAITING_CLIENT_VERSION,
- AWAITING_CLIENT_AUTH_METHOD,
- AWAITING_CLIENT_INIT_msg,
- MAIN_LOOP
-};
-
-class ConnectionMetadata
-{
- public:
- ConnectionMetadata(){};
-
- VncState vncState{VncState::UNSTARTED};
-};
-
-using meta_list = std::vector<ConnectionMetadata>;
-meta_list connectionStates(10);
-
-ConnectionMetadata meta;
-
-template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
-{
- BMCWEB_ROUTE(app, "/kvmws")
- .websocket()
- .onopen([&](crow::websocket::Connection& conn) {
- if (meta.vncState == VncState::UNSTARTED)
- {
- meta.vncState = VncState::AWAITING_CLIENT_VERSION;
- conn.sendBinary(rfb38VersionString);
- }
- else
- { // SHould never happen
- conn.close();
- }
- })
- .onclose(
- [&](crow::websocket::Connection& conn, const std::string& reason) {
- meta.vncState = VncState::UNSTARTED;
- })
- .onmessage([&](crow::websocket::Connection& conn,
- const std::string& data, bool is_binary) {
- switch (meta.vncState)
- {
- case VncState::AWAITING_CLIENT_VERSION:
- {
- std::cout << "Client sent: " << data;
- if (data == rfb38VersionString ||
- data == rfb37VersionString)
- {
- std::string authTypes{
- 1, (uint8_t)RfbAuthScheme::no_authentication};
- conn.sendBinary(authTypes);
- meta.vncState = VncState::AWAITING_CLIENT_AUTH_METHOD;
- }
- else if (data == rfb33VersionString)
- {
- // TODO(ed) Support older protocols
- meta.vncState = VncState::UNSTARTED;
- conn.close();
- }
- else
- {
- // TODO(ed) Support older protocols
- meta.vncState = VncState::UNSTARTED;
- conn.close();
- }
- }
- break;
- case VncState::AWAITING_CLIENT_AUTH_METHOD:
- {
- std::string securityResult{{0, 0, 0, 0}};
- if (data[0] == (uint8_t)RfbAuthScheme::no_authentication)
- {
- meta.vncState = VncState::AWAITING_CLIENT_INIT_msg;
- }
- else
- {
- // Mark auth as failed
- securityResult[3] = 1;
- meta.vncState = VncState::UNSTARTED;
- }
- conn.sendBinary(securityResult);
- }
- break;
- case VncState::AWAITING_CLIENT_INIT_msg:
- {
- // Now send the server initialization
- ServerInitializationMsg serverInitMsg{};
- serverInitMsg.framebufferWidth = 800;
- serverInitMsg.framebufferHeight = 600;
- serverInitMsg.pixelFormat.bitsPerPixel = 32;
- serverInitMsg.pixelFormat.isBigEndian = 0;
- serverInitMsg.pixelFormat.isTrueColor = 1;
- serverInitMsg.pixelFormat.redMax = 255;
- serverInitMsg.pixelFormat.greenMax = 255;
- serverInitMsg.pixelFormat.blueMax = 255;
- serverInitMsg.pixelFormat.redShift = 16;
- serverInitMsg.pixelFormat.greenShift = 8;
- serverInitMsg.pixelFormat.blueShift = 0;
- serverInitMsg.nameLength = 0;
- std::cout << "size: " << sizeof(serverInitMsg);
- // TODO(ed) this is ugly. Crow should really have a span
- // type interface to avoid the copy, but alas, today it does
- // not.
- std::string s(reinterpret_cast<char*>(&serverInitMsg),
- sizeof(serverInitMsg));
- std::cout << "s.size() " << s.size();
- conn.sendBinary(s);
- meta.vncState = VncState::MAIN_LOOP;
- }
- break;
- case VncState::MAIN_LOOP:
- {
- if (data.size() >= sizeof(client_to_server_msg_type))
- {
- auto type =
- static_cast<client_to_server_msg_type>(data[0]);
- std::cout << "Received client message type "
- << static_cast<std::size_t>(type) << "\n";
- switch (type)
- {
- case client_to_server_msg_type::set_pixel_format:
- {
- }
- break;
-
- case client_to_server_msg_type::
- fix_color_map_entries:
- {
- }
- break;
- case client_to_server_msg_type::set_encodings:
- {
- }
- break;
- case client_to_server_msg_type::
- framebuffer_update_request:
- {
- // Make sure the buffer is long enough to handle
- // what we're about to do
- if (data.size() >=
- sizeof(FrameBufferUpdateReq) +
- sizeof(client_to_server_msg_type))
- {
- auto msg = reinterpret_cast<
- const FrameBufferUpdateReq*>(
- data.data() + // NOLINT
- sizeof(client_to_server_msg_type));
- // TODO(ed) find a better way to do this
- // deserialization
-
- // Todo(ed) lifecycle of the video puller
- // and decoder should be with the websocket,
- // not recreated every time
- ast_video::SimpleVideoPuller p;
- p.initialize();
- auto out = p.readVideo();
- ast_video::AstJpegDecoder d;
- d.decode(out.buffer, out.width, out.height,
- out.mode, out.ySelector,
- out.uvSelector);
-
- FramebufferUpdateMsg bufferUpdateMsg;
-
- // If the viewer is requesting a full
- // update, force write of all pixels
-
- FramebufferRectangle thisRect;
- thisRect.x = msg->xPosition;
- thisRect.y = msg->yPosition;
- thisRect.width = out.width;
- thisRect.height = out.height;
- thisRect.encoding = static_cast<uint8_t>(
- encoding_type::raw);
- std::cout << "Encoding is "
- << thisRect.encoding;
- thisRect.data.reserve(
- static_cast<std::size_t>(
- thisRect.width) *
- static_cast<std::size_t>(
- thisRect.height) *
- 4);
- std::cout << "Width " << out.width
- << " Height " << out.height;
-
- for (int i = 0; i < out.width * out.height;
- i++)
- {
- auto& pixel = d.outBuffer[i];
- thisRect.data.push_back(pixel.b);
- thisRect.data.push_back(pixel.g);
- thisRect.data.push_back(pixel.r);
- thisRect.data.push_back(0);
- }
-
- bufferUpdateMsg.rectangles.push_back(
- std::move(thisRect));
- auto serialized =
- serialize(bufferUpdateMsg);
-
- conn.sendBinary(serialized);
-
- } // TODO(Ed) handle error
- }
-
- break;
-
- case client_to_server_msg_type::key_event:
- {
- }
- break;
-
- case client_to_server_msg_type::pointer_event:
- {
- }
- break;
-
- case client_to_server_msg_type::client_cut_text:
- {
- }
- break;
-
- default:
- break;
- }
- }
- }
- break;
- case VncState::UNSTARTED:
- // Error? TODO
- break;
- }
- });
-}
-} // namespace kvm
-} // namespace crow \ No newline at end of file
diff --git a/src/getvideo_main.cpp b/src/getvideo_main.cpp
deleted file mode 100644
index 849c75d539..0000000000
--- a/src/getvideo_main.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <cstdio>
-#include <cstdlib>
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <thread>
-#include <vector>
-
-//#define BUILD_CIMG
-#ifdef BUILD_CIMG
-#define cimg_display 0
-#include <CImg.h>
-#endif
-
-#include <ast_jpeg_decoder.hpp>
-#include <ast_video_puller.hpp>
-
-int main()
-{
- ast_video::RawVideoBuffer out;
- bool have_hardware = false;
- if (access("/dev/video", F_OK) != -1)
- {
- ast_video::SimpleVideoPuller p;
- p.initialize();
- out = p.readVideo();
- }
- else
- {
- FILE *fp = fopen("/home/ed/screendata.bin", "rb");
- if (fp != nullptr)
- {
- size_t newLen = fread(out.buffer.data(), sizeof(char),
- out.buffer.size() * sizeof(long), fp);
- if (ferror(fp) != 0)
- {
- fputs("Error reading file", stderr);
- }
- fclose(fp);
- out.buffer.resize(newLen);
- out.mode = ast_video::YuvMode::YUV444;
- out.width = 800;
- out.height = 600;
- out.ySelector = 0;
- out.uvSelector = 0;
- }
- }
-
- FILE *fp = fopen("/tmp/screendata.bin", "wb");
- fwrite(out.buffer.data(), sizeof(char), out.buffer.size(), fp);
- fclose(fp);
-
- ast_video::AstJpegDecoder d;
- d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
- out.uvSelector);
-#ifdef BUILD_CIMG
- cimg_library::CImg<unsigned char> image(out.width, out.height, 1,
- 3 /*numchannels*/);
- for (int y = 0; y < out.height; y++)
- {
- for (int x = 0; x < out.width; x++)
- {
- auto pixel = d.outBuffer[x + (y * out.width)];
- image(x, y, 0) = pixel.r;
- image(x, y, 1) = pixel.g;
- image(x, y, 2) = pixel.b;
- }
- }
- image.save("/tmp/file2.bmp");
-#endif
-
- std::cout << "Done!\n";
-
- return 1;
-}
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 7c64f4c748..b357b4e1de 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -5,6 +5,7 @@
#include <dbus_monitor.hpp>
#include <dbus_singleton.hpp>
#include <image_upload.hpp>
+#include <kvm_websocket.hpp>
#include <memory>
#include <obmc_console.hpp>
#include <openbmc_dbus_rest.hpp>
@@ -18,7 +19,6 @@
#include <ssl_key_handler.hpp>
#include <string>
#include <token_authorization_middleware.hpp>
-#include <web_kvm.hpp>
#include <webassets.hpp>
#include <webserver_common.hpp>
@@ -77,7 +77,7 @@ int main(int argc, char** argv)
#endif
#ifdef BMCWEB_ENABLE_KVM
- crow::kvm::requestRoutes(app);
+ crow::obmc_kvm::requestRoutes(app);
#endif
#ifdef BMCWEB_ENABLE_REDFISH