mirror of https://github.com/FreeRDP/FreeRDP
Merge remote-tracking branch 'upstream/master' into rail
This commit is contained in:
commit
34e1210f63
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* String Utils
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __STRING_UTILS_H
|
||||
#define __STRING_UTILS_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/unicode.h>
|
||||
|
||||
struct rdp_string
|
||||
{
|
||||
char* ascii;
|
||||
char* unicode;
|
||||
uint32 length;
|
||||
};
|
||||
typedef struct rdp_string rdpString;
|
||||
|
||||
FREERDP_API void freerdp_string_read_length32(STREAM* s, rdpString* string, UNICONV* uniconv);
|
||||
FREERDP_API void freerdp_string_free(rdpString* string);
|
||||
|
||||
#endif /* __STRING_UTILS_H */
|
|
@ -104,6 +104,33 @@ boolean rdp_client_connect(rdpRdp* rdp)
|
|||
return True;
|
||||
}
|
||||
|
||||
boolean rdp_client_disconnect(rdpRdp* rdp)
|
||||
{
|
||||
return transport_disconnect(rdp->transport);
|
||||
}
|
||||
|
||||
boolean rdp_client_redirect(rdpRdp* rdp)
|
||||
{
|
||||
rdpSettings* settings = rdp->settings;
|
||||
rdpRedirection* redirection = rdp->redirection;
|
||||
|
||||
rdp_client_disconnect(rdp);
|
||||
|
||||
rdp->transport->layer = TRANSPORT_LAYER_TCP;
|
||||
settings->redirected_session_id = redirection->sessionID;
|
||||
|
||||
if (redirection->flags & LB_TARGET_NET_ADDRESS)
|
||||
settings->hostname = redirection->targetNetAddress.ascii;
|
||||
|
||||
if (redirection->flags & LB_USERNAME)
|
||||
settings->username = redirection->username.ascii;
|
||||
|
||||
if (redirection->flags & LB_DOMAIN)
|
||||
settings->domain = redirection->domain.ascii;
|
||||
|
||||
return rdp_client_connect(rdp);
|
||||
}
|
||||
|
||||
boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!mcs_recv_connect_response(rdp->mcs, s))
|
||||
|
|
|
@ -45,6 +45,7 @@ enum CONNECTION_STATE
|
|||
};
|
||||
|
||||
boolean rdp_client_connect(rdpRdp* rdp);
|
||||
boolean rdp_client_redirect(rdpRdp* rdp);
|
||||
boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s);
|
||||
|
|
|
@ -602,6 +602,7 @@ rdpRdp* rdp_new(freerdp* instance)
|
|||
rdp->nego = nego_new(rdp->transport);
|
||||
rdp->mcs = mcs_new(rdp->transport);
|
||||
rdp->vchan = vchan_new(instance);
|
||||
rdp->redirection = redirection_new();
|
||||
}
|
||||
|
||||
return rdp;
|
||||
|
@ -625,6 +626,7 @@ void rdp_free(rdpRdp* rdp)
|
|||
nego_free(rdp->nego);
|
||||
mcs_free(rdp->mcs);
|
||||
vchan_free(rdp->vchan);
|
||||
redirection_free(rdp->redirection);
|
||||
xfree(rdp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ typedef struct rdp_rdp rdpRdp;
|
|||
#include "security.h"
|
||||
#include "transport.h"
|
||||
#include "connection.h"
|
||||
#include "redirection.h"
|
||||
#include "capabilities.h"
|
||||
#include "vchan.h"
|
||||
#include "mppc.h"
|
||||
|
@ -122,6 +123,7 @@ struct rdp_rdp
|
|||
struct rdp_update* update;
|
||||
struct rdp_fastpath* fastpath;
|
||||
struct rdp_license* license;
|
||||
struct rdp_redirection* redirection;
|
||||
struct rdp_settings* settings;
|
||||
struct rdp_transport* transport;
|
||||
struct rdp_vchan* vchan;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "connection.h"
|
||||
|
||||
#include "redirection.h"
|
||||
|
||||
void rdp_print_redirection_flags(uint32 flags)
|
||||
|
@ -57,90 +59,98 @@ boolean rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s)
|
|||
{
|
||||
uint16 flags;
|
||||
uint16 length;
|
||||
uint32 sessionID;
|
||||
uint32 redirFlags;
|
||||
uint32 targetNetAddressLength;
|
||||
uint32 loadBalanceInfoLength;
|
||||
uint32 userNameLength;
|
||||
uint32 domainLength;
|
||||
uint32 passwordLength;
|
||||
uint32 targetFQDNLength;
|
||||
uint32 targetNetBiosNameLength;
|
||||
uint32 tsvUrlLength;
|
||||
uint32 targetNetAddressesLength;
|
||||
rdpRedirection* redirection = rdp->redirection;
|
||||
|
||||
stream_read_uint16(s, flags); /* flags (2 bytes) */
|
||||
stream_read_uint16(s, length); /* length (2 bytes) */
|
||||
stream_read_uint32(s, sessionID); /* sessionID (4 bytes) */
|
||||
stream_read_uint32(s, redirFlags); /* redirFlags (4 bytes) */
|
||||
stream_read_uint32(s, redirection->sessionID); /* sessionID (4 bytes) */
|
||||
stream_read_uint32(s, redirection->flags); /* redirFlags (4 bytes) */
|
||||
|
||||
DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, sessionID);
|
||||
DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, redirection->sessionID);
|
||||
|
||||
#ifdef WITH_DEBUG_REDIR
|
||||
rdp_print_redirection_flags(redirFlags);
|
||||
rdp_print_redirection_flags(redirection->flags);
|
||||
#endif
|
||||
|
||||
if (redirFlags & LB_TARGET_NET_ADDRESS)
|
||||
if (redirection->flags & LB_TARGET_NET_ADDRESS)
|
||||
{
|
||||
stream_read_uint32(s, targetNetAddressLength); /* targetNetAddressLength (4 bytes) */
|
||||
stream_seek(s, targetNetAddressLength);
|
||||
freerdp_string_read_length32(s, &redirection->targetNetAddress, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("targetNetAddress: %s", redirection->targetNetAddress.ascii);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_LOAD_BALANCE_INFO)
|
||||
if (redirection->flags & LB_LOAD_BALANCE_INFO)
|
||||
{
|
||||
stream_read_uint32(s, loadBalanceInfoLength); /* loadBalanceInfoLength (4 bytes) */
|
||||
stream_seek(s, loadBalanceInfoLength);
|
||||
freerdp_string_read_length32(s, &redirection->loadBalanceInfo, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("loadBalanceInfo: %s", redirection->loadBalanceInfo.ascii);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_USERNAME)
|
||||
if (redirection->flags & LB_USERNAME)
|
||||
{
|
||||
stream_read_uint32(s, userNameLength); /* userNameLength (4 bytes) */
|
||||
stream_seek(s, userNameLength);
|
||||
freerdp_string_read_length32(s, &redirection->username, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("username: %s", redirection->username.ascii);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_DOMAIN)
|
||||
if (redirection->flags & LB_DOMAIN)
|
||||
{
|
||||
stream_read_uint32(s, domainLength); /* domainLength (4 bytes) */
|
||||
stream_seek(s, domainLength);
|
||||
freerdp_string_read_length32(s, &redirection->domain, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("domain: %s", redirection->domain.ascii);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_PASSWORD)
|
||||
if (redirection->flags & LB_PASSWORD)
|
||||
{
|
||||
stream_read_uint32(s, passwordLength); /* passwordLength (4 bytes) */
|
||||
stream_seek(s, passwordLength);
|
||||
freerdp_string_read_length32(s, &redirection->password, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("password: %s", redirection->password.ascii);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_TARGET_FQDN)
|
||||
if (redirection->flags & LB_TARGET_FQDN)
|
||||
{
|
||||
stream_read_uint32(s, targetFQDNLength); /* targetFQDNLength (4 bytes) */
|
||||
stream_seek(s, targetFQDNLength);
|
||||
freerdp_string_read_length32(s, &redirection->targetFQDN, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("targetFQDN: %s", redirection->targetFQDN.ascii);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_TARGET_NETBIOS_NAME)
|
||||
if (redirection->flags & LB_TARGET_NETBIOS_NAME)
|
||||
{
|
||||
stream_read_uint32(s, targetNetBiosNameLength); /* targetNetBiosNameLength (4 bytes) */
|
||||
stream_seek(s, targetNetBiosNameLength);
|
||||
freerdp_string_read_length32(s, &redirection->targetNetBiosName, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("targetNetBiosName: %s", redirection->targetNetBiosName.ascii);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_CLIENT_TSV_URL)
|
||||
if (redirection->flags & LB_CLIENT_TSV_URL)
|
||||
{
|
||||
stream_read_uint32(s, tsvUrlLength); /* tsvUrlLength (4 bytes) */
|
||||
stream_seek(s, tsvUrlLength);
|
||||
freerdp_string_read_length32(s, &redirection->tsvUrl, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("tsvUrl: %s", redirection->tsvUrl.ascii);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_TARGET_NET_ADDRESSES)
|
||||
if (redirection->flags & LB_TARGET_NET_ADDRESSES)
|
||||
{
|
||||
stream_read_uint32(s, targetNetAddressesLength); /* targetNetAddressesLength (4 bytes) */
|
||||
stream_seek(s, targetNetAddressesLength);
|
||||
uint32 count;
|
||||
uint32 targetNetAddressesLength;
|
||||
|
||||
stream_read_uint32(s, targetNetAddressesLength);
|
||||
|
||||
stream_read_uint32(s, redirection->targetNetAddressesCount);
|
||||
count = redirection->targetNetAddressesCount;
|
||||
|
||||
redirection->targetNetAddresses = (rdpString*) xzalloc(count * sizeof(rdpString));
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
freerdp_string_read_length32(s, redirection->targetNetAddresses, rdp->settings->uniconv);
|
||||
DEBUG_REDIR("targetNetAddresses: %s", redirection->targetNetAddresses->ascii);
|
||||
redirection->targetNetAddresses++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
stream_seek(s, 8); /* pad (8 bytes) */
|
||||
|
||||
rdp_client_redirect(rdp);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean rdp_recv_redirection_packet(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
rdp_recv_server_redirection_pdu(rdp, s);
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -152,3 +162,43 @@ boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s)
|
|||
return True;
|
||||
}
|
||||
|
||||
rdpRedirection* redirection_new()
|
||||
{
|
||||
rdpRedirection* redirection;
|
||||
|
||||
redirection = (rdpRedirection*) xzalloc(sizeof(rdpRedirection));
|
||||
|
||||
if (redirection != NULL)
|
||||
{
|
||||
freerdp_string_free(&redirection->tsvUrl);
|
||||
freerdp_string_free(&redirection->username);
|
||||
freerdp_string_free(&redirection->domain);
|
||||
freerdp_string_free(&redirection->password);
|
||||
freerdp_string_free(&redirection->targetFQDN);
|
||||
freerdp_string_free(&redirection->loadBalanceInfo);
|
||||
freerdp_string_free(&redirection->targetNetBiosName);
|
||||
freerdp_string_free(&redirection->targetNetAddress);
|
||||
|
||||
if (redirection->targetNetAddresses != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < redirection->targetNetAddressesCount; i++)
|
||||
freerdp_string_free(&redirection->targetNetAddresses[i]);
|
||||
|
||||
xfree(redirection->targetNetAddresses);
|
||||
}
|
||||
}
|
||||
|
||||
return redirection;
|
||||
}
|
||||
|
||||
void redirection_free(rdpRedirection* redirection)
|
||||
{
|
||||
if (redirection != NULL)
|
||||
{
|
||||
xfree(redirection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/string.h>
|
||||
|
||||
/* Redirection Flags */
|
||||
#define LB_TARGET_NET_ADDRESS 0x00000001
|
||||
|
@ -41,9 +42,29 @@
|
|||
#define LB_CLIENT_TSV_URL 0x00001000
|
||||
#define LB_SERVER_TSV_CAPABLE 0x00002000
|
||||
|
||||
struct rdp_redirection
|
||||
{
|
||||
uint32 flags;
|
||||
uint32 sessionID;
|
||||
rdpString tsvUrl;
|
||||
rdpString username;
|
||||
rdpString domain;
|
||||
rdpString password;
|
||||
rdpString targetFQDN;
|
||||
rdpString loadBalanceInfo;
|
||||
rdpString targetNetBiosName;
|
||||
rdpString targetNetAddress;
|
||||
uint32 targetNetAddressesCount;
|
||||
rdpString* targetNetAddresses;
|
||||
};
|
||||
typedef struct rdp_redirection rdpRedirection;
|
||||
|
||||
boolean rdp_recv_redirection_packet(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s);
|
||||
|
||||
rdpRedirection* redirection_new();
|
||||
void redirection_free(rdpRedirection* redirection);
|
||||
|
||||
#ifdef WITH_DEBUG_REDIR
|
||||
#define DEBUG_REDIR(fmt, ...) DEBUG_CLASS(REDIR, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
|
|
|
@ -231,9 +231,6 @@ rdpTcp* tcp_new(rdpSettings* settings)
|
|||
{
|
||||
tcp->sockfd = -1;
|
||||
tcp->settings = settings;
|
||||
tcp->connect = tcp_connect;
|
||||
tcp->disconnect = tcp_disconnect;
|
||||
tcp->set_blocking_mode = tcp_set_blocking_mode;
|
||||
}
|
||||
|
||||
return tcp;
|
||||
|
|
|
@ -36,9 +36,6 @@
|
|||
#endif
|
||||
|
||||
typedef struct rdp_tcp rdpTcp;
|
||||
typedef boolean (*TcpConnect) (rdpTcp* tcp, const char* hostname, uint16 port);
|
||||
typedef boolean (*TcpDisconnect) (rdpTcp* tcp);
|
||||
typedef boolean (*TcpSetBlockingMode) (rdpTcp* tcp, boolean blocking);
|
||||
|
||||
struct rdp_tcp
|
||||
{
|
||||
|
@ -46,9 +43,6 @@ struct rdp_tcp
|
|||
char ip_address[32];
|
||||
uint8 mac_address[6];
|
||||
struct rdp_settings* settings;
|
||||
TcpConnect connect;
|
||||
TcpDisconnect disconnect;
|
||||
TcpSetBlockingMode set_blocking_mode;
|
||||
#ifdef _WIN32
|
||||
WSAEVENT wsa_event;
|
||||
#endif
|
||||
|
|
|
@ -235,10 +235,6 @@ rdpTls* tls_new()
|
|||
|
||||
if (tls != NULL)
|
||||
{
|
||||
tls->connect = tls_connect;
|
||||
tls->accept = tls_accept;
|
||||
tls->disconnect = tls_disconnect;
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
}
|
||||
|
|
|
@ -29,18 +29,12 @@
|
|||
#include <freerdp/utils/stream.h>
|
||||
|
||||
typedef struct rdp_tls rdpTls;
|
||||
typedef boolean (*TlsConnect) (rdpTls* tls);
|
||||
typedef boolean (*TlsAccept) (rdpTls* tls, const char* cert_file, const char* privatekey_file);
|
||||
typedef boolean (*TlsDisconnect) (rdpTls* tls);
|
||||
|
||||
struct rdp_tls
|
||||
{
|
||||
SSL* ssl;
|
||||
int sockfd;
|
||||
SSL_CTX* ctx;
|
||||
TlsConnect connect;
|
||||
TlsAccept accept;
|
||||
TlsDisconnect disconnect;
|
||||
};
|
||||
|
||||
boolean tls_connect(rdpTls* tls);
|
||||
|
|
|
@ -60,7 +60,7 @@ STREAM* transport_send_stream_init(rdpTransport* transport, int size)
|
|||
|
||||
boolean transport_connect(rdpTransport* transport, const char* hostname, uint16 port)
|
||||
{
|
||||
return transport->tcp->connect(transport->tcp, hostname, port);
|
||||
return tcp_connect(transport->tcp, hostname, port);
|
||||
}
|
||||
|
||||
void transport_attach(rdpTransport* transport, int sockfd)
|
||||
|
@ -70,9 +70,10 @@ void transport_attach(rdpTransport* transport, int sockfd)
|
|||
|
||||
boolean transport_disconnect(rdpTransport* transport)
|
||||
{
|
||||
if (transport->tls)
|
||||
IFCALL(transport->tls->disconnect, transport->tls);
|
||||
return transport->tcp->disconnect(transport->tcp);
|
||||
if (transport->layer == TRANSPORT_LAYER_TLS)
|
||||
return tls_disconnect(transport->tls);
|
||||
else
|
||||
return tcp_disconnect(transport->tcp);
|
||||
}
|
||||
|
||||
boolean transport_connect_rdp(rdpTransport* transport)
|
||||
|
@ -355,15 +356,10 @@ int transport_check_fds(rdpTransport* transport)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void transport_init(rdpTransport* transport)
|
||||
{
|
||||
transport->layer = TRANSPORT_LAYER_TCP;
|
||||
}
|
||||
|
||||
boolean transport_set_blocking_mode(rdpTransport* transport, boolean blocking)
|
||||
{
|
||||
transport->blocking = blocking;
|
||||
return transport->tcp->set_blocking_mode(transport->tcp, blocking);
|
||||
return tcp_set_blocking_mode(transport->tcp, blocking);
|
||||
}
|
||||
|
||||
rdpTransport* transport_new(rdpSettings* settings)
|
||||
|
@ -389,6 +385,8 @@ rdpTransport* transport_new(rdpSettings* settings)
|
|||
transport->send_stream = stream_new(BUFFER_SIZE);
|
||||
|
||||
transport->blocking = True;
|
||||
|
||||
transport->layer = TRANSPORT_LAYER_TCP;
|
||||
}
|
||||
|
||||
return transport;
|
||||
|
|
|
@ -86,18 +86,31 @@ void rfx_decode_ycbcr_to_rgb(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf
|
|||
{
|
||||
sint16 y, cb, cr;
|
||||
sint16 r, g, b;
|
||||
|
||||
int i;
|
||||
|
||||
/**
|
||||
* The decoded YCbCr coeffectients are represented as 11.5 fixed-point numbers:
|
||||
*
|
||||
* 1 sign bit + 10 integer bits + 5 fractional bits
|
||||
*
|
||||
* However only 7 integer bits will be actually used since the value range is [-128.0, 127.0].
|
||||
* In other words, the decoded coeffectients is scaled by << 5 when intepreted as sint16.
|
||||
* It was scaled in the quantization phase, so we must scale it back here.
|
||||
*/
|
||||
for (i = 0; i < 4096; i++)
|
||||
{
|
||||
y = y_r_buf[i] + 128;
|
||||
y = (y_r_buf[i] >> 5) + 128;
|
||||
cb = cb_g_buf[i];
|
||||
cr = cr_b_buf[i];
|
||||
r = (y + cr + (cr >> 2) + (cr >> 3) + (cr >> 5));
|
||||
/* 1.403 >> 5 = 0.000010110011100(b) */
|
||||
r = y + ((cr >> 5) + (cr >> 7) + (cr >> 8) + (cr >> 11) + (cr >> 12) + (cr >> 13));
|
||||
y_r_buf[i] = MINMAX(r, 0, 255);
|
||||
g = (y - ((cb >> 2) + (cb >> 4) + (cb >> 5)) - ((cr >> 1) + (cr >> 3) + (cr >> 4) + (cr >> 5)));
|
||||
/* 0.344 >> 5 = 0.000000101100000(b), 0.714 >> 5 = 0.000001011011011(b) */
|
||||
g = y - ((cb >> 7) + (cb >> 9) + (cb >> 10)) -
|
||||
((cr >> 6) + (cr >> 8) + (cr >> 9) + (cr >> 11) + (cr >> 12) + (cr >> 13));
|
||||
cb_g_buf[i] = MINMAX(g, 0, 255);
|
||||
b = (y + cb + (cb >> 1) + (cb >> 2) + (cb >> 6));
|
||||
/* 1.77 >> 5 = 0.000011100010100(b) */
|
||||
b = y + ((cb >> 5) + (cb >> 6) + (cb >> 7) + (cb >> 11) + (cb >> 13));
|
||||
cr_b_buf[i] = MINMAX(b, 0, 255);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ static void rfx_dwt_2d_encode_block(sint16* buffer, sint16* dwt, int subband_wid
|
|||
src = buffer + y * total_width + x;
|
||||
|
||||
/* H */
|
||||
*h = (src[total_width] - ((src[0] + src[n < subband_width - 1 ? 2 * total_width : total_width]) >> 1)) >> 1;
|
||||
*h = (src[total_width] - ((src[0] + src[n < subband_width - 1 ? 2 * total_width : 0]) >> 1)) >> 1;
|
||||
|
||||
/* L */
|
||||
*l = src[0] + (n == 0 ? *h : (*(h - total_width) + *h) >> 1);
|
||||
|
|
|
@ -123,20 +123,37 @@ void rfx_encode_rgb_to_ycbcr(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf
|
|||
{
|
||||
sint16 y, cb, cr;
|
||||
sint16 r, g, b;
|
||||
|
||||
int i;
|
||||
|
||||
/**
|
||||
* The encoded YCbCr coeffectients are represented as 11.5 fixed-point numbers:
|
||||
*
|
||||
* 1 sign bit + 10 integer bits + 5 fractional bits
|
||||
*
|
||||
* However only 7 integer bits will be actually used since the value range is [-128.0, 127.0].
|
||||
* In other words, the encoded coeffectients is scaled by << 5 when intepreted as sint16.
|
||||
* It will be scaled down to original during the quantization phase.
|
||||
*/
|
||||
for (i = 0; i < 4096; i++)
|
||||
{
|
||||
r = y_r_buf[i];
|
||||
g = cb_g_buf[i];
|
||||
b = cr_b_buf[i];
|
||||
y = ((r >> 2) + (r >> 5) + (r >> 6)) + ((g >> 1) + (g >> 4) + (g >> 6) + (g >> 7)) +
|
||||
((b >> 4) + (b >> 5) + (b >> 6) + (b >> 7));
|
||||
y_r_buf[i] = MINMAX(y, 0, 255) - 128;
|
||||
cb = 0 - ((r >> 3) + (r >> 5) + (r >> 6)) - ((g >> 2) + (g >> 4) + (g >> 6)) + (b >> 1);
|
||||
cb_g_buf[i] = MINMAX(cb, -128, 127);
|
||||
cr = (r >> 1) - ((g >> 2) + (g >> 3) + (g >> 5) + (g >> 6)) - ((b >> 4) + (b >> 6));
|
||||
cr_b_buf[i] = MINMAX(cr, -128, 127);
|
||||
/* 0.299 << 5 = 1001.10010001(b), 0.587 << 5 = 10010.11001000(b), 0.114 << 5 = 11.10100101(b) */
|
||||
y = ((r << 3) + (r) + (r >> 1) + (r >> 4) + (r >> 7)) +
|
||||
((g << 4) + (g << 1) + (g >> 1) + (g >> 2) + (g >> 5)) +
|
||||
((b << 1) + (b) + (b >> 1) + (b >> 3) + (b >> 6) + (b >> 7));
|
||||
y_r_buf[i] = MINMAX(y - 4096, -4096, 4095);
|
||||
/* 0.168935 << 5 = 101.01100111(b), 0.331665 << 5 = 1010.10011100(b), 0.50059 << 5 = 10000.00000100(b) */
|
||||
cb = 0 - ((r << 2) + (r) + (r >> 2) + (r >> 3) + (r >> 5)) -
|
||||
((g << 3) + (g << 1) + (g >> 1) + (g >> 4) + (g >> 5) + (g >> 6)) +
|
||||
((b << 4) + (b >> 6));
|
||||
cb_g_buf[i] = MINMAX(cb, -4096, 4095);
|
||||
/* 0.499813 << 5 = 1111.11111110(b), 0.418531 << 5 = 1101.01100100(b), 0.081282 << 5 = 10.10011001(b) */
|
||||
cr = ((r << 4) - (r >> 7)) -
|
||||
((g << 3) + (g << 2) + (g) + (g >> 2) + (g >> 3) + (g >> 6)) -
|
||||
((b << 1) + (b >> 1) + (b >> 4) + (b >> 5) + (b >> 7));
|
||||
cr_b_buf[i] = MINMAX(cr, -4096, 4095);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,9 @@ static void rfx_quantization_decode_block(sint16* buffer, int buffer_size, uint3
|
|||
{
|
||||
sint16* dst;
|
||||
|
||||
if (factor <= 6)
|
||||
if (factor == 0)
|
||||
return;
|
||||
|
||||
factor -= 6;
|
||||
for (dst = buffer; buffer_size > 0; dst++, buffer_size--)
|
||||
{
|
||||
*dst <<= factor;
|
||||
|
@ -35,26 +34,28 @@ static void rfx_quantization_decode_block(sint16* buffer, int buffer_size, uint3
|
|||
|
||||
void rfx_quantization_decode(sint16* buffer, const uint32* quantization_values)
|
||||
{
|
||||
rfx_quantization_decode_block(buffer, 1024, quantization_values[8]); /* HL1 */
|
||||
rfx_quantization_decode_block(buffer + 1024, 1024, quantization_values[7]); /* LH1 */
|
||||
rfx_quantization_decode_block(buffer + 2048, 1024, quantization_values[9]); /* HH1 */
|
||||
rfx_quantization_decode_block(buffer + 3072, 256, quantization_values[5]); /* HL2 */
|
||||
rfx_quantization_decode_block(buffer + 3328, 256, quantization_values[4]); /* LH2 */
|
||||
rfx_quantization_decode_block(buffer + 3584, 256, quantization_values[6]); /* HH2 */
|
||||
rfx_quantization_decode_block(buffer + 3840, 64, quantization_values[2]); /* HL3 */
|
||||
rfx_quantization_decode_block(buffer + 3904, 64, quantization_values[1]); /* LH3 */
|
||||
rfx_quantization_decode_block(buffer + 3868, 64, quantization_values[3]); /* HH3 */
|
||||
rfx_quantization_decode_block(buffer + 4032, 64, quantization_values[0]); /* LL3 */
|
||||
/* Scale the values so that they are represented as 11.5 fixed-point number */
|
||||
rfx_quantization_decode_block(buffer, 4096, 5);
|
||||
|
||||
rfx_quantization_decode_block(buffer, 1024, quantization_values[8] - 6); /* HL1 */
|
||||
rfx_quantization_decode_block(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
|
||||
rfx_quantization_decode_block(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
|
||||
rfx_quantization_decode_block(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
|
||||
rfx_quantization_decode_block(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
|
||||
rfx_quantization_decode_block(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
|
||||
rfx_quantization_decode_block(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
|
||||
rfx_quantization_decode_block(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
|
||||
rfx_quantization_decode_block(buffer + 3868, 64, quantization_values[3] - 6); /* HH3 */
|
||||
rfx_quantization_decode_block(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
|
||||
}
|
||||
|
||||
static void rfx_quantization_encode_block(sint16* buffer, int buffer_size, uint32 factor)
|
||||
{
|
||||
sint16* dst;
|
||||
|
||||
if (factor <= 6)
|
||||
if (factor == 0)
|
||||
return;
|
||||
|
||||
factor -= 6;
|
||||
for (dst = buffer; buffer_size > 0; dst++, buffer_size--)
|
||||
{
|
||||
*dst >>= factor;
|
||||
|
@ -63,14 +64,17 @@ static void rfx_quantization_encode_block(sint16* buffer, int buffer_size, uint3
|
|||
|
||||
void rfx_quantization_encode(sint16* buffer, const uint32* quantization_values)
|
||||
{
|
||||
rfx_quantization_encode_block(buffer, 1024, quantization_values[8]); /* HL1 */
|
||||
rfx_quantization_encode_block(buffer + 1024, 1024, quantization_values[7]); /* LH1 */
|
||||
rfx_quantization_encode_block(buffer + 2048, 1024, quantization_values[9]); /* HH1 */
|
||||
rfx_quantization_encode_block(buffer + 3072, 256, quantization_values[5]); /* HL2 */
|
||||
rfx_quantization_encode_block(buffer + 3328, 256, quantization_values[4]); /* LH2 */
|
||||
rfx_quantization_encode_block(buffer + 3584, 256, quantization_values[6]); /* HH2 */
|
||||
rfx_quantization_encode_block(buffer + 3840, 64, quantization_values[2]); /* HL3 */
|
||||
rfx_quantization_encode_block(buffer + 3904, 64, quantization_values[1]); /* LH3 */
|
||||
rfx_quantization_encode_block(buffer + 3868, 64, quantization_values[3]); /* HH3 */
|
||||
rfx_quantization_encode_block(buffer + 4032, 64, quantization_values[0]); /* LL3 */
|
||||
rfx_quantization_encode_block(buffer, 1024, quantization_values[8] - 6); /* HL1 */
|
||||
rfx_quantization_encode_block(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
|
||||
rfx_quantization_encode_block(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
|
||||
rfx_quantization_encode_block(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
|
||||
rfx_quantization_encode_block(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
|
||||
rfx_quantization_encode_block(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
|
||||
rfx_quantization_encode_block(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
|
||||
rfx_quantization_encode_block(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
|
||||
rfx_quantization_encode_block(buffer + 3868, 64, quantization_values[3] - 6); /* HH3 */
|
||||
rfx_quantization_encode_block(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
|
||||
|
||||
/* The coefficients are scaled by << 5 at RGB->YCbCr phase, so we round it back here */
|
||||
rfx_quantization_encode_block(buffer, 4096, 5);
|
||||
}
|
||||
|
|
|
@ -68,49 +68,59 @@ static void rfx_decode_ycbcr_to_rgb_sse2(sint16* y_r_buffer, sint16* cb_g_buffer
|
|||
}
|
||||
for (i = 0; i < (4096 * sizeof(sint16) / sizeof(__m128i)); i++)
|
||||
{
|
||||
/* y = y_r_buf[i] + 128; */
|
||||
/* y = (y_r_buf[i] >> 5) + 128; */
|
||||
y = _mm_load_si128(&y_r_buf[i]);
|
||||
y = _mm_add_epi16(y, _mm_set1_epi16(128));
|
||||
y = _mm_add_epi16(_mm_srai_epi16(y, 5), _mm_set1_epi16(128));
|
||||
|
||||
/* cr = cr_b_buf[i]; */
|
||||
cr = _mm_load_si128(&cr_b_buf[i]);
|
||||
|
||||
/* r = between(y + cr + (cr >> 2) + (cr >> 3) + (cr >> 5), 0, 255); */
|
||||
r = _mm_add_epi16(y, cr);
|
||||
r = _mm_add_epi16(r, _mm_srai_epi16(cr, 2));
|
||||
r = _mm_add_epi16(r, _mm_srai_epi16(cr, 3));
|
||||
r = _mm_add_epi16(r, _mm_srai_epi16(cr, 5));
|
||||
/* r = y + ((cr >> 5) + (cr >> 7) + (cr >> 8) + (cr >> 11) + (cr >> 12) + (cr >> 13)); */
|
||||
/* y_r_buf[i] = MINMAX(r, 0, 255); */
|
||||
r = _mm_add_epi16(y, _mm_srai_epi16(cr, 5));
|
||||
r = _mm_add_epi16(r, _mm_srai_epi16(cr, 7));
|
||||
r = _mm_add_epi16(r, _mm_srai_epi16(cr, 8));
|
||||
r = _mm_add_epi16(r, _mm_srai_epi16(cr, 11));
|
||||
r = _mm_add_epi16(r, _mm_srai_epi16(cr, 12));
|
||||
r = _mm_add_epi16(r, _mm_srai_epi16(cr, 13));
|
||||
_mm_between_epi16(r, zero, max);
|
||||
_mm_store_si128(&y_r_buf[i], r);
|
||||
|
||||
/* cb = cb_g_buf[i]; */
|
||||
cb = _mm_load_si128(&cb_g_buf[i]);
|
||||
|
||||
/* g = between(y - (cb >> 2) - (cb >> 4) - (cb >> 5) - (cr >> 1) - (cr >> 3) - (cr >> 4) - (cr >> 5), 0, 255); */
|
||||
g = _mm_sub_epi16(y, _mm_srai_epi16(cb, 2));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cb, 4));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cb, 5));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 1));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 3));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 4));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 5));
|
||||
/* g = y - ((cb >> 7) + (cb >> 9) + (cb >> 10)) -
|
||||
((cr >> 6) + (cr >> 8) + (cr >> 9) + (cr >> 11) + (cr >> 12) + (cr >> 13)); */
|
||||
/* cb_g_buf[i] = MINMAX(g, 0, 255); */
|
||||
g = _mm_sub_epi16(y, _mm_srai_epi16(cb, 7));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cb, 9));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cb, 10));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 6));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 8));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 9));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 11));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 12));
|
||||
g = _mm_sub_epi16(g, _mm_srai_epi16(cr, 13));
|
||||
_mm_between_epi16(g, zero, max);
|
||||
_mm_store_si128(&cb_g_buf[i], g);
|
||||
_mm_store_si128(&cb_g_buf[i], g);
|
||||
|
||||
/* b = between(y + cb + (cb >> 1) + (cb >> 2) + (cb >> 6), 0, 255); */
|
||||
b = _mm_add_epi16(y, cb);
|
||||
b = _mm_add_epi16(b, _mm_srai_epi16(cb, 1));
|
||||
b = _mm_add_epi16(b, _mm_srai_epi16(cb, 2));
|
||||
/* b = y + ((cb >> 5) + (cb >> 6) + (cb >> 7) + (cb >> 11) + (cb >> 13)); */
|
||||
/* cr_b_buf[i] = MINMAX(b, 0, 255); */
|
||||
b = _mm_add_epi16(y, _mm_srai_epi16(cb, 5));
|
||||
b = _mm_add_epi16(b, _mm_srai_epi16(cb, 6));
|
||||
b = _mm_add_epi16(b, _mm_srai_epi16(cb, 7));
|
||||
b = _mm_add_epi16(b, _mm_srai_epi16(cb, 11));
|
||||
b = _mm_add_epi16(b, _mm_srai_epi16(cb, 13));
|
||||
_mm_between_epi16(b, zero, max);
|
||||
_mm_store_si128(&cr_b_buf[i], b);
|
||||
}
|
||||
}
|
||||
|
||||
/* The encodec YCbCr coeffectients are represented as 11.5 fixed-point numbers. See rfx_encode.c */
|
||||
static void rfx_encode_rgb_to_ycbcr_sse2(sint16* y_r_buffer, sint16* cb_g_buffer, sint16* cr_b_buffer)
|
||||
{
|
||||
__m128i min = _mm_set1_epi16(-128);
|
||||
__m128i max = _mm_set1_epi16(127);
|
||||
__m128i min = _mm_set1_epi16(-128 << 5);
|
||||
__m128i max = _mm_set1_epi16(127 << 5);
|
||||
|
||||
__m128i* y_r_buf = (__m128i*) y_r_buffer;
|
||||
__m128i* cb_g_buf = (__m128i*) cb_g_buffer;
|
||||
|
@ -142,42 +152,64 @@ static void rfx_encode_rgb_to_ycbcr_sse2(sint16* y_r_buffer, sint16* cb_g_buffer
|
|||
/* b = cr_b_buf[i]; */
|
||||
b = _mm_load_si128(&cr_b_buf[i]);
|
||||
|
||||
/* y = ((r >> 2) + (r >> 5) + (r >> 6)) + ((g >> 1) + (g >> 4) + (g >> 6) + (g >> 7)) +
|
||||
((b >> 4) + (b >> 5) + (b >> 6) + (b >> 7)); */
|
||||
/* y_r_buf[i] = MINMAX(y, 0, 255) - 128; */
|
||||
y = _mm_add_epi16(_mm_srai_epi16(r, 2), _mm_srai_epi16(r, 5));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(r, 6));
|
||||
/* y = ((r << 3) + (r) + (r >> 1) + (r >> 4) + (r >> 7)) +
|
||||
((g << 4) + (g << 1) + (g >> 1) + (g >> 2) + (g >> 5)) +
|
||||
((b << 1) + (b) + (b >> 1) + (b >> 3) + (b >> 6) + (b >> 7)); */
|
||||
/* y_r_buf[i] = MINMAX(y, 0, (255 << 5)) - (128 << 5); */
|
||||
y = _mm_add_epi16(_mm_slli_epi16(r, 3), r);
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(r, 1));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(r, 4));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(r, 7));
|
||||
y = _mm_add_epi16(y, _mm_slli_epi16(g, 4));
|
||||
y = _mm_add_epi16(y, _mm_slli_epi16(g, 1));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(g, 1));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(g, 4));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(g, 6));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(g, 7));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(b, 4));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(b, 5));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(g, 2));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(g, 5));
|
||||
y = _mm_add_epi16(y, _mm_slli_epi16(b, 1));
|
||||
y = _mm_add_epi16(y, b);
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(b, 1));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(b, 3));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(b, 6));
|
||||
y = _mm_add_epi16(y, _mm_srai_epi16(b, 7));
|
||||
y = _mm_add_epi16(y, min);
|
||||
_mm_between_epi16(y, min, max);
|
||||
_mm_store_si128(&y_r_buf[i], y);
|
||||
|
||||
/* cb = 0 - ((r >> 3) + (r >> 5) + (r >> 6)) - ((g >> 2) + (g >> 4) + (g >> 6)) + (b >> 1); */
|
||||
/* cb_g_buf[i] = MINMAX(cb, -128, 127); */
|
||||
cb = _mm_sub_epi16(_mm_srai_epi16(b, 1), _mm_srai_epi16(r, 3));
|
||||
/* cb = 0 - ((r << 2) + (r) + (r >> 2) + (r >> 3) + (r >> 5)) -
|
||||
((g << 3) + (g << 1) + (g >> 1) + (g >> 4) + (g >> 5) + (g >> 6)) +
|
||||
((b << 4) + (b >> 6)); */
|
||||
/* cb_g_buf[i] = MINMAX(cb, (-128 << 5), (127 << 5)); */
|
||||
cb = _mm_add_epi16(_mm_slli_epi16(b, 4), _mm_srai_epi16(b, 6));
|
||||
cb = _mm_sub_epi16(cb, _mm_slli_epi16(r, 2));
|
||||
cb = _mm_sub_epi16(cb, r);
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(r, 2));
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(r, 3));
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(r, 5));
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(r, 6));
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(g, 2));
|
||||
cb = _mm_sub_epi16(cb, _mm_slli_epi16(g, 3));
|
||||
cb = _mm_sub_epi16(cb, _mm_slli_epi16(g, 1));
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(g, 1));
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(g, 4));
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(g, 5));
|
||||
cb = _mm_sub_epi16(cb, _mm_srai_epi16(g, 6));
|
||||
_mm_between_epi16(cb, min, max);
|
||||
_mm_store_si128(&cb_g_buf[i], cb);
|
||||
|
||||
/* cr = (r >> 1) - ((g >> 2) + (g >> 3) + (g >> 5) + (g >> 6)) - ((b >> 4) + (b >> 6)); */
|
||||
/* cr_b_buf[i] = MINMAX(cr, -128, 127); */
|
||||
cr = _mm_sub_epi16(_mm_srai_epi16(r, 1), _mm_srai_epi16(g, 2));
|
||||
/* cr = ((r << 4) - (r >> 7)) -
|
||||
((g << 3) + (g << 2) + (g) + (g >> 2) + (g >> 3) + (g >> 6)) -
|
||||
((b << 1) + (b >> 1) + (b >> 4) + (b >> 5) + (b >> 7)); */
|
||||
/* cr_b_buf[i] = MINMAX(cr, (-128 << 5), (127 << 5)); */
|
||||
cr = _mm_sub_epi16(_mm_slli_epi16(r, 4), _mm_srai_epi16(r, 7));
|
||||
cr = _mm_sub_epi16(cr, _mm_slli_epi16(g, 3));
|
||||
cr = _mm_sub_epi16(cr, _mm_slli_epi16(g, 2));
|
||||
cr = _mm_sub_epi16(cr, g);
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(g, 2));
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(g, 3));
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(g, 5));
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(g, 6));
|
||||
cr = _mm_sub_epi16(cr, _mm_slli_epi16(b, 1));
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(b, 1));
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(b, 4));
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(b, 6));
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(b, 5));
|
||||
cr = _mm_sub_epi16(cr, _mm_srai_epi16(b, 7));
|
||||
_mm_between_epi16(cr, min, max);
|
||||
_mm_store_si128(&cr_b_buf[i], cr);
|
||||
}
|
||||
|
@ -186,17 +218,16 @@ static void rfx_encode_rgb_to_ycbcr_sse2(sint16* y_r_buffer, sint16* cb_g_buffer
|
|||
static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
rfx_quantization_decode_block_sse2(sint16* buffer, const int buffer_size, const uint32 factor)
|
||||
{
|
||||
int shift = factor-6;
|
||||
if (shift <= 0)
|
||||
if (factor == 0)
|
||||
return;
|
||||
|
||||
|
||||
__m128i a;
|
||||
__m128i * ptr = (__m128i*) buffer;
|
||||
__m128i * buf_end = (__m128i*) (buffer + buffer_size);
|
||||
do
|
||||
{
|
||||
a = _mm_load_si128(ptr);
|
||||
a = _mm_slli_epi16(a, shift);
|
||||
a = _mm_slli_epi16(a, factor);
|
||||
_mm_store_si128(ptr, a);
|
||||
|
||||
ptr++;
|
||||
|
@ -207,23 +238,24 @@ static void rfx_quantization_decode_sse2(sint16* buffer, const uint32* quantizat
|
|||
{
|
||||
_mm_prefetch_buffer((char*) buffer, 4096 * sizeof(sint16));
|
||||
|
||||
rfx_quantization_decode_block_sse2(buffer, 1024, quantization_values[8]); /* HL1 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 1024, 1024, quantization_values[7]); /* LH1 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 2048, 1024, quantization_values[9]); /* HH1 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3072, 256, quantization_values[5]); /* HL2 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3328, 256, quantization_values[4]); /* LH2 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3584, 256, quantization_values[6]); /* HH2 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3840, 64, quantization_values[2]); /* HL3 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3904, 64, quantization_values[1]); /* LH3 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3868, 64, quantization_values[3]); /* HH3 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 4032, 64, quantization_values[0]); /* LL3 */
|
||||
rfx_quantization_decode_block_sse2(buffer, 4096, 5);
|
||||
|
||||
rfx_quantization_decode_block_sse2(buffer, 1024, quantization_values[8] - 6); /* HL1 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 3868, 64, quantization_values[3] - 6); /* HH3 */
|
||||
rfx_quantization_decode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
|
||||
}
|
||||
|
||||
static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
rfx_quantization_encode_block_sse2(sint16* buffer, const int buffer_size, const uint32 factor)
|
||||
{
|
||||
int shift = factor-6;
|
||||
if (shift <= 0)
|
||||
if (factor == 0)
|
||||
return;
|
||||
|
||||
__m128i a;
|
||||
|
@ -232,7 +264,7 @@ rfx_quantization_encode_block_sse2(sint16* buffer, const int buffer_size, const
|
|||
do
|
||||
{
|
||||
a = _mm_load_si128(ptr);
|
||||
a = _mm_srai_epi16(a, shift);
|
||||
a = _mm_srai_epi16(a, factor);
|
||||
_mm_store_si128(ptr, a);
|
||||
|
||||
ptr++;
|
||||
|
@ -243,16 +275,18 @@ static void rfx_quantization_encode_sse2(sint16* buffer, const uint32* quantizat
|
|||
{
|
||||
_mm_prefetch_buffer((char*) buffer, 4096 * sizeof(sint16));
|
||||
|
||||
rfx_quantization_encode_block_sse2(buffer, 1024, quantization_values[8]); /* HL1 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 1024, 1024, quantization_values[7]); /* LH1 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 2048, 1024, quantization_values[9]); /* HH1 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3072, 256, quantization_values[5]); /* HL2 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3328, 256, quantization_values[4]); /* LH2 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3584, 256, quantization_values[6]); /* HH2 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3840, 64, quantization_values[2]); /* HL3 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3904, 64, quantization_values[1]); /* LH3 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3868, 64, quantization_values[3]); /* HH3 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 4032, 64, quantization_values[0]); /* LL3 */
|
||||
rfx_quantization_encode_block_sse2(buffer, 1024, quantization_values[8] - 6); /* HL1 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 3868, 64, quantization_values[3] - 6); /* HH3 */
|
||||
rfx_quantization_encode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
|
||||
|
||||
rfx_quantization_encode_block_sse2(buffer, 4096, 5);
|
||||
}
|
||||
|
||||
static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
|
@ -482,7 +516,7 @@ rfx_dwt_2d_encode_block_vert_sse2(sint16* src, sint16* l, sint16* h, int subband
|
|||
if (n < subband_width - 1)
|
||||
src_2n_2 = _mm_load_si128((__m128i*) (src + 2 * total_width));
|
||||
else
|
||||
src_2n_2 = src_2n_1;
|
||||
src_2n_2 = src_2n;
|
||||
|
||||
/* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */
|
||||
|
||||
|
@ -534,7 +568,7 @@ rfx_dwt_2d_encode_block_horiz_sse2(sint16* src, sint16* l, sint16* h, int subban
|
|||
/* The following 3 Set operations consumes more than half of the total DWT processing time! */
|
||||
src_2n = _mm_set_epi16(src[14], src[12], src[10], src[8], src[6], src[4], src[2], src[0]);
|
||||
src_2n_1 = _mm_set_epi16(src[15], src[13], src[11], src[9], src[7], src[5], src[3], src[1]);
|
||||
src_2n_2 = _mm_set_epi16(n == subband_width - 8 ? src[15] : src[16],
|
||||
src_2n_2 = _mm_set_epi16(n == subband_width - 8 ? src[14] : src[16],
|
||||
src[14], src[12], src[10], src[8], src[6], src[4], src[2]);
|
||||
|
||||
/* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */
|
||||
|
|
|
@ -40,6 +40,7 @@ set(FREERDP_UTILS_SRCS
|
|||
sleep.c
|
||||
stopwatch.c
|
||||
stream.c
|
||||
string.c
|
||||
svc_plugin.c
|
||||
thread.c
|
||||
unicode.c
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* String Utils
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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 <freerdp/utils/memory.h>
|
||||
|
||||
#include <freerdp/utils/string.h>
|
||||
|
||||
void freerdp_string_read_length32(STREAM* s, rdpString* string, UNICONV* uniconv)
|
||||
{
|
||||
stream_read_uint32(s, string->length);
|
||||
string->unicode = (char*) xmalloc(string->length);
|
||||
stream_read(s, string->unicode, string->length);
|
||||
string->ascii = freerdp_uniconv_in(uniconv, (uint8*) string->unicode, string->length);
|
||||
}
|
||||
|
||||
void freerdp_string_free(rdpString* string)
|
||||
{
|
||||
if (string->unicode != NULL)
|
||||
xfree(string->unicode);
|
||||
|
||||
if (string->ascii != NULL)
|
||||
xfree(string->ascii);
|
||||
}
|
Loading…
Reference in New Issue