testImage rotation added to testServer, Qt4Designer project files
This commit is contained in:
@@ -43,6 +43,7 @@ endif
|
||||
|
||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
USR_CXXFLAGS += -Wall -Wextra
|
||||
|
||||
-include $(TOP)/configure/CONFIG_SITE.local
|
||||
-include $(TOP)/../CONFIG.local
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
||||
#
|
||||
# Create a file RELEASE.local pointing to your PVDATA and
|
||||
# EPICS_BASE build directories, and optionally GTEST e.g.
|
||||
# PVDATA = /home/install/epics/pvDataCPP
|
||||
# Create a file RELEASE.local pointing to your PVDATA, PVCOMMON
|
||||
# and EPICS_BASE build directories, and optionally GTEST e.g.
|
||||
# PVCOMMON = /home/install/epicsV4/pvCommonCPP
|
||||
# PVDATA = /home/install/epicsV4/pvDataCPP
|
||||
# EPICS_BASE = /home/install/epics/base
|
||||
# # GTEST not used
|
||||
|
||||
|
||||
1
pvAccessCPP.config
Normal file
1
pvAccessCPP.config
Normal file
@@ -0,0 +1 @@
|
||||
// ADD PREDEFINED MACROS HERE!
|
||||
1
pvAccessCPP.creator
Normal file
1
pvAccessCPP.creator
Normal file
@@ -0,0 +1 @@
|
||||
[General]
|
||||
189
pvAccessCPP.files
Normal file
189
pvAccessCPP.files
Normal file
@@ -0,0 +1,189 @@
|
||||
configure/CONFIG
|
||||
configure/CONFIG_SITE
|
||||
configure/RELEASE
|
||||
configure/RELEASE.local
|
||||
configure/RULES
|
||||
configure/RULES.ioc
|
||||
configure/RULES_DIRS
|
||||
configure/RULES_TOP
|
||||
documentation/pvAccessCPP.html
|
||||
documentation/README
|
||||
jenkins/cloudbees_build
|
||||
pvAccessApp/ca/caConstants.h
|
||||
pvAccessApp/ca/clientFactory.cpp
|
||||
pvAccessApp/ca/clientFactory.h
|
||||
pvAccessApp/ca/pvVersion.cpp
|
||||
pvAccessApp/ca/pvVersion.h
|
||||
pvAccessApp/client/pvAccess.cpp
|
||||
pvAccessApp/client/pvAccess.h
|
||||
pvAccessApp/client/pvAccess.h.orig
|
||||
pvAccessApp/factory/ChannelAccessFactory.cpp
|
||||
pvAccessApp/factory/CreateRequestFactory.cpp
|
||||
pvAccessApp/mb/pvAccessMB.cpp
|
||||
pvAccessApp/mb/pvAccessMB.h
|
||||
pvAccessApp/O.linux-x86_64/abstractResponseHandler.d
|
||||
pvAccessApp/O.linux-x86_64/baseChannelRequester.d
|
||||
pvAccessApp/O.linux-x86_64/beaconEmitter.d
|
||||
pvAccessApp/O.linux-x86_64/beaconHandler.d
|
||||
pvAccessApp/O.linux-x86_64/beaconServerStatusProvider.d
|
||||
pvAccessApp/O.linux-x86_64/blockingClientTCPTransport.d
|
||||
pvAccessApp/O.linux-x86_64/blockingServerTCPTransport.d
|
||||
pvAccessApp/O.linux-x86_64/blockingTCPAcceptor.d
|
||||
pvAccessApp/O.linux-x86_64/blockingTCPConnector.d
|
||||
pvAccessApp/O.linux-x86_64/blockingTCPTransport.d
|
||||
pvAccessApp/O.linux-x86_64/blockingUDPConnector.d
|
||||
pvAccessApp/O.linux-x86_64/blockingUDPTransport.d
|
||||
pvAccessApp/O.linux-x86_64/ChannelAccessFactory.d
|
||||
pvAccessApp/O.linux-x86_64/clientContextImpl.d
|
||||
pvAccessApp/O.linux-x86_64/clientFactory.d
|
||||
pvAccessApp/O.linux-x86_64/configuration.d
|
||||
pvAccessApp/O.linux-x86_64/CreateRequestFactory.d
|
||||
pvAccessApp/O.linux-x86_64/hexDump.d
|
||||
pvAccessApp/O.linux-x86_64/inetAddressUtil.d
|
||||
pvAccessApp/O.linux-x86_64/introspectionRegistry.d
|
||||
pvAccessApp/O.linux-x86_64/libpvAccess.a
|
||||
pvAccessApp/O.linux-x86_64/libpvAccess.so
|
||||
pvAccessApp/O.linux-x86_64/logger.d
|
||||
pvAccessApp/O.linux-x86_64/pvAccess.d
|
||||
pvAccessApp/O.linux-x86_64/pvAccessMB.d
|
||||
pvAccessApp/O.linux-x86_64/pvVersion.d
|
||||
pvAccessApp/O.linux-x86_64/referenceCountingLock.d
|
||||
pvAccessApp/O.linux-x86_64/responseHandlers.d
|
||||
pvAccessApp/O.linux-x86_64/rpcClient.d
|
||||
pvAccessApp/O.linux-x86_64/rpcServer.d
|
||||
pvAccessApp/O.linux-x86_64/serializationHelper.d
|
||||
pvAccessApp/O.linux-x86_64/serverChannelImpl.d
|
||||
pvAccessApp/O.linux-x86_64/serverContext.d
|
||||
pvAccessApp/O.linux-x86_64/simpleChannelSearchManagerImpl.d
|
||||
pvAccessApp/O.linux-x86_64/transportRegistry.d
|
||||
pvAccessApp/remote/abstractResponseHandler.cpp
|
||||
pvAccessApp/remote/beaconHandler.cpp
|
||||
pvAccessApp/remote/beaconHandler.h
|
||||
pvAccessApp/remote/blockingClientTCPTransport.cpp
|
||||
pvAccessApp/remote/blockingServerTCPTransport.cpp
|
||||
pvAccessApp/remote/blockingTCP.h
|
||||
pvAccessApp/remote/blockingTCPAcceptor.cpp
|
||||
pvAccessApp/remote/blockingTCPConnector.cpp
|
||||
pvAccessApp/remote/blockingTCPTransport.cpp
|
||||
pvAccessApp/remote/blockingUDP.h
|
||||
pvAccessApp/remote/blockingUDPConnector.cpp
|
||||
pvAccessApp/remote/blockingUDPTransport.cpp
|
||||
pvAccessApp/remote/channelSearchManager.h
|
||||
pvAccessApp/remote/remote.h
|
||||
pvAccessApp/remote/serializationHelper.cpp
|
||||
pvAccessApp/remote/serializationHelper.h
|
||||
pvAccessApp/remote/simpleChannelSearchManagerImpl.cpp
|
||||
pvAccessApp/remote/simpleChannelSearchManagerImpl.h
|
||||
pvAccessApp/remote/transportRegistry.cpp
|
||||
pvAccessApp/remote/transportRegistry.h
|
||||
pvAccessApp/remoteClient/clientContextImpl.cpp
|
||||
pvAccessApp/remoteClient/clientContextImpl.h
|
||||
pvAccessApp/remoteClient/clientContextImpl.h.orig
|
||||
pvAccessApp/rpcClient/rpcClient.cpp
|
||||
pvAccessApp/rpcClient/rpcClient.h
|
||||
pvAccessApp/rpcService/rpcServer.cpp
|
||||
pvAccessApp/rpcService/rpcServer.h
|
||||
pvAccessApp/rpcService/rpcService.h
|
||||
pvAccessApp/server/baseChannelRequester.cpp
|
||||
pvAccessApp/server/baseChannelRequester.h
|
||||
pvAccessApp/server/beaconEmitter.cpp
|
||||
pvAccessApp/server/beaconEmitter.h
|
||||
pvAccessApp/server/beaconServerStatusProvider.cpp
|
||||
pvAccessApp/server/beaconServerStatusProvider.h
|
||||
pvAccessApp/server/responseHandlers.cpp
|
||||
pvAccessApp/server/responseHandlers.h
|
||||
pvAccessApp/server/serverChannelImpl.cpp
|
||||
pvAccessApp/server/serverChannelImpl.h
|
||||
pvAccessApp/server/serverContext.cpp
|
||||
pvAccessApp/server/serverContext.h
|
||||
pvAccessApp/utils/configuration.cpp
|
||||
pvAccessApp/utils/configuration.h
|
||||
pvAccessApp/utils/hexDump.cpp
|
||||
pvAccessApp/utils/hexDump.h
|
||||
pvAccessApp/utils/inetAddressUtil.cpp
|
||||
pvAccessApp/utils/inetAddressUtil.h
|
||||
pvAccessApp/utils/introspectionRegistry.cpp
|
||||
pvAccessApp/utils/introspectionRegistry.h
|
||||
pvAccessApp/utils/likely.h
|
||||
pvAccessApp/utils/logger.cpp
|
||||
pvAccessApp/utils/logger.h
|
||||
pvAccessApp/utils/namedLockPattern.h
|
||||
pvAccessApp/utils/referenceCountingLock.cpp
|
||||
pvAccessApp/utils/referenceCountingLock.h
|
||||
scripts/gcovr
|
||||
testApp/client/O.linux-x86_64/testCreateRequest
|
||||
testApp/client/O.linux-x86_64/testCreateRequest.d
|
||||
testApp/client/O.linux-x86_64/testStartStop
|
||||
testApp/client/O.linux-x86_64/testStartStop.d
|
||||
testApp/client/MockClientImpl.cpp
|
||||
testApp/client/testChannelAccessFactory.cpp
|
||||
testApp/client/testCreateRequest.cpp
|
||||
testApp/client/testMockClient.cpp
|
||||
testApp/client/testStartStop.cpp
|
||||
testApp/remote/O.linux-x86_64/eget
|
||||
testApp/remote/O.linux-x86_64/eget.d
|
||||
testApp/remote/O.linux-x86_64/pvget
|
||||
testApp/remote/O.linux-x86_64/pvget.d
|
||||
testApp/remote/O.linux-x86_64/pvput
|
||||
testApp/remote/O.linux-x86_64/pvput.d
|
||||
testApp/remote/O.linux-x86_64/pvrpc
|
||||
testApp/remote/O.linux-x86_64/pvrpc.d
|
||||
testApp/remote/O.linux-x86_64/rpcServiceExample
|
||||
testApp/remote/O.linux-x86_64/rpcServiceExample.d
|
||||
testApp/remote/O.linux-x86_64/testBlockingTCPClnt
|
||||
testApp/remote/O.linux-x86_64/testBlockingTCPClnt.d
|
||||
testApp/remote/O.linux-x86_64/testBlockingTCPSrv
|
||||
testApp/remote/O.linux-x86_64/testBlockingTCPSrv.d
|
||||
testApp/remote/O.linux-x86_64/testBlockingUDPClnt
|
||||
testApp/remote/O.linux-x86_64/testBlockingUDPClnt.d
|
||||
testApp/remote/O.linux-x86_64/testBlockingUDPSrv
|
||||
testApp/remote/O.linux-x86_64/testBlockingUDPSrv.d
|
||||
testApp/remote/O.linux-x86_64/testChannelConnect
|
||||
testApp/remote/O.linux-x86_64/testChannelConnect.d
|
||||
testApp/remote/O.linux-x86_64/testGetPerformance
|
||||
testApp/remote/O.linux-x86_64/testGetPerformance.d
|
||||
testApp/remote/O.linux-x86_64/testRemoteClientImpl
|
||||
testApp/remote/O.linux-x86_64/testRemoteClientImpl.d
|
||||
testApp/remote/O.linux-x86_64/testServer
|
||||
testApp/remote/O.linux-x86_64/testServer.d
|
||||
testApp/remote/O.linux-x86_64/testServerContext
|
||||
testApp/remote/O.linux-x86_64/testServerContext.d
|
||||
testApp/remote/eget.cpp
|
||||
testApp/remote/epicsv4Grayscale.h
|
||||
testApp/remote/pvget.cpp
|
||||
testApp/remote/pvput.cpp
|
||||
testApp/remote/pvrpc.cpp
|
||||
testApp/remote/pvutils.cpp
|
||||
testApp/remote/pvutils.h
|
||||
testApp/remote/rpcServiceExample.cpp
|
||||
testApp/remote/testADCSim.cpp
|
||||
testApp/remote/testBeaconEmitter.cpp
|
||||
testApp/remote/testBeaconHandler.cpp
|
||||
testApp/remote/testBlockingTCPClnt.cpp
|
||||
testApp/remote/testBlockingTCPSrv.cpp
|
||||
testApp/remote/testBlockingUDPClnt.cpp
|
||||
testApp/remote/testBlockingUDPSrv.cpp
|
||||
testApp/remote/testChannelConnect.cpp
|
||||
testApp/remote/testChannelSearchManager.cpp
|
||||
testApp/remote/testGetPerformance.cpp
|
||||
testApp/remote/testNTImage.cpp
|
||||
testApp/remote/testRemoteClientImpl.cpp
|
||||
testApp/remote/testServer.cpp
|
||||
testApp/remote/testServerContext.cpp
|
||||
testApp/utils/O.linux-x86_64/atomicBooleanTest.d
|
||||
testApp/utils/O.linux-x86_64/hexDumpTest.d
|
||||
testApp/utils/O.linux-x86_64/inetAddressUtilsTest.d
|
||||
testApp/utils/O.linux-x86_64/testUtils
|
||||
testApp/utils/atomicBooleanTest.cpp
|
||||
testApp/utils/configurationTest.cpp
|
||||
testApp/utils/hexDumpTest.cpp
|
||||
testApp/utils/inetAddressUtilsTest.cpp
|
||||
testApp/utils/introspectionRegistryTest.cpp
|
||||
testApp/utils/loggerTest.cpp
|
||||
testApp/utils/namedLockPatternTest.cpp
|
||||
testApp/utils/transportRegistryTest.cpp
|
||||
DEMO
|
||||
Doxyfile
|
||||
README
|
||||
runTestServer
|
||||
TODO
|
||||
10
pvAccessCPP.includes
Normal file
10
pvAccessCPP.includes
Normal file
@@ -0,0 +1,10 @@
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/ca
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/client
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/mb
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/remote
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/remoteClient
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/rpcClient
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/rpcService
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/server
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/pvAccessApp/utils
|
||||
/home/msekoranja/epicsV4/pvAccessCPP/testApp/remote
|
||||
File diff suppressed because it is too large
Load Diff
@@ -75,7 +75,6 @@ epics::pvData::StructureConstPtr makeImageStruc()
|
||||
return imageStruc;
|
||||
}
|
||||
|
||||
|
||||
void setImageArrayValues(PVStructure::shared_pointer const & imagePV)
|
||||
{
|
||||
String id = imagePV->getStructure()->getID();
|
||||
@@ -142,3 +141,498 @@ void initImage(PVStructure::shared_pointer const & imagePV)
|
||||
setImageMetadataValues(imagePV);
|
||||
}
|
||||
|
||||
void rotateImage(PVStructure::shared_pointer const & imagePV, float deg)
|
||||
{
|
||||
PVScalarArrayPtr value = static_pointer_cast<PVScalarArray>(imagePV->getSubField("value"));
|
||||
PVIntArrayPtr dim = static_pointer_cast<PVIntArray>(imagePV->getScalarArrayField("dim", pvInt));
|
||||
// dim[] = { rows, columns }
|
||||
int32 rows, cols;
|
||||
size_t dims = dim->getLength();
|
||||
|
||||
IntArrayData data;
|
||||
dim->get(0, dims, data);
|
||||
cols = data.data[0];
|
||||
rows = data.data[1];
|
||||
|
||||
PVByteArrayPtr array = static_pointer_cast<PVByteArray>(value);
|
||||
|
||||
ByteArrayData dimg;
|
||||
size_t imgSize = array->getLength();
|
||||
array->get(0, imgSize, dimg);
|
||||
|
||||
double fi = 3.141592653589793238462 * deg / 180.0;
|
||||
double cosFi = 16.0 * cos(fi);
|
||||
double sinFi = 16.0 * sin(fi);
|
||||
|
||||
int32 cx = cols/2;
|
||||
int32 cy = rows/2;
|
||||
|
||||
int32 colsm2 = cols-2;
|
||||
int32 rowsm2 = rows-2;
|
||||
|
||||
int8_t* img = &dimg.data[0];
|
||||
|
||||
for (int32 y = 0; y < rows; y++)
|
||||
{
|
||||
int8_t* imgline = img + y*cols;
|
||||
int32 dcy = y - cy;
|
||||
for (int32 x = 0; x < cols; x++)
|
||||
{
|
||||
int32 dcx = x - cx;
|
||||
|
||||
int32 tnx = static_cast<int32>(cosFi*dcx + sinFi*dcy);
|
||||
int32 tny = static_cast<int32>(-sinFi*dcx + cosFi*dcy);
|
||||
|
||||
int32 nx = (tnx >> 4) + cx;
|
||||
int32 ny = (tny >> 4) + cy;
|
||||
|
||||
if (nx < 0 || ny < 0 || nx > colsm2 || ny > rowsm2)
|
||||
{
|
||||
imgline[x] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int8_t* srcline = epicsv4_raw + ny*cols;
|
||||
|
||||
int32 xf = tnx & 0x0F;
|
||||
int32 yf = tny & 0x0F;
|
||||
|
||||
int32 v00 = (16 - xf) * (16 - yf) * (srcline[nx] + 128);
|
||||
int32 v10 = xf * (16 - yf) * (srcline[nx + 1] + 128);
|
||||
int32 v01 = (16 - xf) * yf * (srcline[cols + nx] + 128);
|
||||
int32 v11 = xf * yf * (srcline[cols + nx + 1] + 128);
|
||||
uint8_t val = static_cast<uint8_t>((v00 + v01 + v10 + v11 + 128) / 256);
|
||||
imgline[x] = static_cast<int32>(val) - 128;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
array->put(0, imgSize, img, 0);
|
||||
|
||||
PVIntPtr uniqueIdField = imagePV->getIntField(String("uniqueId"));
|
||||
uniqueIdField->put(uniqueIdField->get()+1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rotateAMColorFastLow(uint32 *datad,
|
||||
int32 w,
|
||||
int32 h,
|
||||
int32 wpld,
|
||||
uint32 *datas,
|
||||
int32 wpls,
|
||||
float angle,
|
||||
uint32 colorval);
|
||||
|
||||
void rotateRGBImage(PVStructure::shared_pointer const & imagePV, float deg)
|
||||
{
|
||||
PVScalarArrayPtr value = static_pointer_cast<PVScalarArray>(imagePV->getSubField("value"));
|
||||
PVIntArrayPtr dim = static_pointer_cast<PVIntArray>(imagePV->getScalarArrayField("dim", pvInt));
|
||||
// dim[] = { rows, columns }
|
||||
int32 rows, cols;
|
||||
size_t dims = dim->getLength();
|
||||
|
||||
IntArrayData data;
|
||||
dim->get(0, dims, data);
|
||||
cols = data.data[0];
|
||||
rows = data.data[1];
|
||||
|
||||
PVIntArrayPtr array = static_pointer_cast<PVIntArray>(value);
|
||||
|
||||
IntArrayData dimg;
|
||||
size_t imgSize = array->getLength();
|
||||
array->get(0, imgSize, dimg);
|
||||
|
||||
rotateAMColorFastLow((uint32*)&dimg.data[0],
|
||||
cols,
|
||||
rows,
|
||||
cols,
|
||||
(uint32*)&dimg.data[0],
|
||||
cols,
|
||||
3.141592653589793238462 * deg / 180.0,
|
||||
0x00000000);
|
||||
|
||||
array->put(0, imgSize, &dimg.data[0], 0);
|
||||
|
||||
PVIntPtr uniqueIdField = imagePV->getIntField(String("uniqueId"));
|
||||
uniqueIdField->put(uniqueIdField->get()+1);
|
||||
|
||||
}
|
||||
|
||||
/*====================================================================*
|
||||
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||||
-
|
||||
- Redistribution and use in source and binary forms, with or without
|
||||
- modification, are permitted provided that the following conditions
|
||||
- are met:
|
||||
- 1. Redistributions of source code must retain the above copyright
|
||||
- notice, this list of conditions and the following disclaimer.
|
||||
- 2. Redistributions in binary form must reproduce the above
|
||||
- copyright notice, this list of conditions and the following
|
||||
- disclaimer in the documentation and/or other materials
|
||||
- provided with the distribution.
|
||||
-
|
||||
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
|
||||
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*====================================================================*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Fast RGB color rotation about center *
|
||||
*------------------------------------------------------------------*/
|
||||
/*!
|
||||
* rotateAMColorFastLow()
|
||||
*
|
||||
* This is a special simplification of area mapping with division
|
||||
* of each pixel into 16 sub-pixels. The exact coefficients that
|
||||
* should be used are the same as for the 4x linear interpolation
|
||||
* scaling case, and are given there. I tried to approximate these
|
||||
* as weighted coefficients with a maximum sum of 4, which
|
||||
* allows us to do the arithmetic in parallel for the R, G and B
|
||||
* components in a 32 bit pixel. However, there are three reasons
|
||||
* for not doing that:
|
||||
* (1) the loss of accuracy in the parallel implementation
|
||||
* is visually significant
|
||||
* (2) the parallel implementation (described below) is slower
|
||||
* (3) the parallel implementation requires allocation of
|
||||
* a temporary color image
|
||||
*
|
||||
* There are 16 cases for the choice of the subpixel, and
|
||||
* for each, the mapping to the relevant source
|
||||
* pixels is as follows:
|
||||
*
|
||||
* subpixel src pixel weights
|
||||
* -------- -----------------
|
||||
* 0 sp1
|
||||
* 1 (3 * sp1 + sp2) / 4
|
||||
* 2 (sp1 + sp2) / 2
|
||||
* 3 (sp1 + 3 * sp2) / 4
|
||||
* 4 (3 * sp1 + sp3) / 4
|
||||
* 5 (9 * sp1 + 3 * sp2 + 3 * sp3 + sp4) / 16
|
||||
* 6 (3 * sp1 + 3 * sp2 + sp3 + sp4) / 8
|
||||
* 7 (3 * sp1 + 9 * sp2 + sp3 + 3 * sp4) / 16
|
||||
* 8 (sp1 + sp3) / 2
|
||||
* 9 (3 * sp1 + sp2 + 3 * sp3 + sp4) / 8
|
||||
* 10 (sp1 + sp2 + sp3 + sp4) / 4
|
||||
* 11 (sp1 + 3 * sp2 + sp3 + 3 * sp4) / 8
|
||||
* 12 (sp1 + 3 * sp3) / 4
|
||||
* 13 (3 * sp1 + sp2 + 9 * sp3 + 3 * sp4) / 16
|
||||
* 14 (sp1 + sp2 + 3 * sp3 + 3 * sp4) / 8
|
||||
* 15 (sp1 + 3 * sp2 + 3 * sp3 + 9 * sp4) / 16
|
||||
*
|
||||
* Another way to visualize this is to consider the area mapping
|
||||
* (or linear interpolation) coefficients for the pixel sp1.
|
||||
* Expressed in fourths, they can be written as asymmetric matrix:
|
||||
*
|
||||
* 4 3 2 1
|
||||
* 3 2.25 1.5 0.75
|
||||
* 2 1.5 1 0.5
|
||||
* 1 0.75 0.5 0.25
|
||||
*
|
||||
* The coefficients for the three neighboring pixels can be
|
||||
* similarly written.
|
||||
*
|
||||
* This is implemented here, where, for each color component,
|
||||
* we inline its extraction from each participating word,
|
||||
* construct the linear combination, and combine the results
|
||||
* into the destination 32 bit RGB pixel, using the appropriate shifts.
|
||||
*
|
||||
* It is interesting to note that an alternative method, where
|
||||
* we do the arithmetic on the 32 bit pixels directly (after
|
||||
* shifting the components so they won't overflow into each other)
|
||||
* is significantly inferior. Because we have only 8 bits for
|
||||
* internal overflows, which can be distributed as 2, 3, 3, it
|
||||
* is impossible to add these with the correct linear
|
||||
* interpolation coefficients, which require a sum of up to 16.
|
||||
* Rounding off to a sum of 4 causes appreciable visual artifacts
|
||||
* in the rotated image. The code for the inferior method
|
||||
* can be found in prog/rotatefastalt.c, for reference.
|
||||
*
|
||||
* *** Warning: explicit assumption about RGB component ordering ***
|
||||
*/
|
||||
void
|
||||
rotateAMColorFastLow(uint32 *datad,
|
||||
int32 w,
|
||||
int32 h,
|
||||
int32 wpld,
|
||||
uint32 *datas,
|
||||
int32 wpls,
|
||||
float angle,
|
||||
uint32 colorval)
|
||||
{
|
||||
int32 i, j, xcen, ycen, wm2, hm2;
|
||||
int32 xdif, ydif, xpm, ypm, xp, yp, xf, yf;
|
||||
uint32 word1, word2, word3, word4, red, blue, green;
|
||||
uint32 *pword, *lines, *lined;
|
||||
float sina, cosa;
|
||||
|
||||
xcen = w / 2;
|
||||
wm2 = w - 2;
|
||||
ycen = h / 2;
|
||||
hm2 = h - 2;
|
||||
sina = 4. * sin(angle);
|
||||
cosa = 4. * cos(angle);
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
ydif = ycen - i;
|
||||
lined = datad + i * wpld;
|
||||
for (j = 0; j < w; j++) {
|
||||
xdif = xcen - j;
|
||||
xpm = (int32)(-xdif * cosa - ydif * sina);
|
||||
ypm = (int32)(-ydif * cosa + xdif * sina);
|
||||
xp = xcen + (xpm >> 2);
|
||||
yp = ycen + (ypm >> 2);
|
||||
xf = xpm & 0x03;
|
||||
yf = ypm & 0x03;
|
||||
|
||||
/* if off the edge, write input grayval */
|
||||
if (xp < 0 || yp < 0 || xp > wm2 || yp > hm2) {
|
||||
*(lined + j) = colorval;
|
||||
continue;
|
||||
}
|
||||
|
||||
lines = datas + yp * wpls;
|
||||
pword = lines + xp;
|
||||
|
||||
switch (xf + 4 * yf)
|
||||
{
|
||||
case 0:
|
||||
*(lined + j) = *pword;
|
||||
break;
|
||||
case 1:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
red = 3 * (word1 >> 24) + (word2 >> 24);
|
||||
green = 3 * ((word1 >> 16) & 0xff) +
|
||||
((word2 >> 16) & 0xff);
|
||||
blue = 3 * ((word1 >> 8) & 0xff) +
|
||||
((word2 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 22) & 0xff000000) |
|
||||
((green << 14) & 0x00ff0000) |
|
||||
((blue << 6) & 0x0000ff00);
|
||||
break;
|
||||
case 2:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
red = (word1 >> 24) + (word2 >> 24);
|
||||
green = ((word1 >> 16) & 0xff) + ((word2 >> 16) & 0xff);
|
||||
blue = ((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 23) & 0xff000000) |
|
||||
((green << 15) & 0x00ff0000) |
|
||||
((blue << 7) & 0x0000ff00);
|
||||
break;
|
||||
case 3:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
red = (word1 >> 24) + 3 * (word2 >> 24);
|
||||
green = ((word1 >> 16) & 0xff) +
|
||||
3 * ((word2 >> 16) & 0xff);
|
||||
blue = ((word1 >> 8) & 0xff) +
|
||||
3 * ((word2 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 22) & 0xff000000) |
|
||||
((green << 14) & 0x00ff0000) |
|
||||
((blue << 6) & 0x0000ff00);
|
||||
break;
|
||||
case 4:
|
||||
word1 = *pword;
|
||||
word3 = *(pword + wpls);
|
||||
red = 3 * (word1 >> 24) + (word3 >> 24);
|
||||
green = 3 * ((word1 >> 16) & 0xff) +
|
||||
((word3 >> 16) & 0xff);
|
||||
blue = 3 * ((word1 >> 8) & 0xff) +
|
||||
((word3 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 22) & 0xff000000) |
|
||||
((green << 14) & 0x00ff0000) |
|
||||
((blue << 6) & 0x0000ff00);
|
||||
break;
|
||||
case 5:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = 9 * (word1 >> 24) + 3 * (word2 >> 24) +
|
||||
3 * (word3 >> 24) + (word4 >> 24);
|
||||
green = 9 * ((word1 >> 16) & 0xff) +
|
||||
3 * ((word2 >> 16) & 0xff) +
|
||||
3 * ((word3 >> 16) & 0xff) +
|
||||
((word4 >> 16) & 0xff);
|
||||
blue = 9 * ((word1 >> 8) & 0xff) +
|
||||
3 * ((word2 >> 8) & 0xff) +
|
||||
3 * ((word3 >> 8) & 0xff) +
|
||||
((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 20) & 0xff000000) |
|
||||
((green << 12) & 0x00ff0000) |
|
||||
((blue << 4) & 0x0000ff00);
|
||||
break;
|
||||
case 6:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = 3 * (word1 >> 24) + 3 * (word2 >> 24) +
|
||||
(word3 >> 24) + (word4 >> 24);
|
||||
green = 3 * ((word1 >> 16) & 0xff) +
|
||||
3 * ((word2 >> 16) & 0xff) +
|
||||
((word3 >> 16) & 0xff) +
|
||||
((word4 >> 16) & 0xff);
|
||||
blue = 3 * ((word1 >> 8) & 0xff) +
|
||||
3 * ((word2 >> 8) & 0xff) +
|
||||
((word3 >> 8) & 0xff) +
|
||||
((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 21) & 0xff000000) |
|
||||
((green << 13) & 0x00ff0000) |
|
||||
((blue << 5) & 0x0000ff00);
|
||||
break;
|
||||
case 7:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = 3 * (word1 >> 24) + 9 * (word2 >> 24) +
|
||||
(word3 >> 24) + 3 * (word4 >> 24);
|
||||
green = 3 * ((word1 >> 16) & 0xff) +
|
||||
9 * ((word2 >> 16) & 0xff) +
|
||||
((word3 >> 16) & 0xff) +
|
||||
3 * ((word4 >> 16) & 0xff);
|
||||
blue = 3 * ((word1 >> 8) & 0xff) +
|
||||
9 * ((word2 >> 8) & 0xff) +
|
||||
((word3 >> 8) & 0xff) +
|
||||
3 * ((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 20) & 0xff000000) |
|
||||
((green << 12) & 0x00ff0000) |
|
||||
((blue << 4) & 0x0000ff00);
|
||||
break;
|
||||
case 8:
|
||||
word1 = *pword;
|
||||
word3 = *(pword + wpls);
|
||||
red = (word1 >> 24) + (word3 >> 24);
|
||||
green = ((word1 >> 16) & 0xff) + ((word3 >> 16) & 0xff);
|
||||
blue = ((word1 >> 8) & 0xff) + ((word3 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 23) & 0xff000000) |
|
||||
((green << 15) & 0x00ff0000) |
|
||||
((blue << 7) & 0x0000ff00);
|
||||
break;
|
||||
case 9:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = 3 * (word1 >> 24) + (word2 >> 24) +
|
||||
3 * (word3 >> 24) + (word4 >> 24);
|
||||
green = 3 * ((word1 >> 16) & 0xff) + ((word2 >> 16) & 0xff) +
|
||||
3 * ((word3 >> 16) & 0xff) + ((word4 >> 16) & 0xff);
|
||||
blue = 3 * ((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff) +
|
||||
3 * ((word3 >> 8) & 0xff) + ((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 21) & 0xff000000) |
|
||||
((green << 13) & 0x00ff0000) |
|
||||
((blue << 5) & 0x0000ff00);
|
||||
break;
|
||||
case 10:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = (word1 >> 24) + (word2 >> 24) +
|
||||
(word3 >> 24) + (word4 >> 24);
|
||||
green = ((word1 >> 16) & 0xff) + ((word2 >> 16) & 0xff) +
|
||||
((word3 >> 16) & 0xff) + ((word4 >> 16) & 0xff);
|
||||
blue = ((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff) +
|
||||
((word3 >> 8) & 0xff) + ((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 22) & 0xff000000) |
|
||||
((green << 14) & 0x00ff0000) |
|
||||
((blue << 6) & 0x0000ff00);
|
||||
break;
|
||||
case 11:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = (word1 >> 24) + 3 * (word2 >> 24) +
|
||||
(word3 >> 24) + 3 * (word4 >> 24);
|
||||
green = ((word1 >> 16) & 0xff) + 3 * ((word2 >> 16) & 0xff) +
|
||||
((word3 >> 16) & 0xff) + 3 * ((word4 >> 16) & 0xff);
|
||||
blue = ((word1 >> 8) & 0xff) + 3 * ((word2 >> 8) & 0xff) +
|
||||
((word3 >> 8) & 0xff) + 3 * ((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 21) & 0xff000000) |
|
||||
((green << 13) & 0x00ff0000) |
|
||||
((blue << 5) & 0x0000ff00);
|
||||
break;
|
||||
case 12:
|
||||
word1 = *pword;
|
||||
word3 = *(pword + wpls);
|
||||
red = (word1 >> 24) + 3 * (word3 >> 24);
|
||||
green = ((word1 >> 16) & 0xff) +
|
||||
3 * ((word3 >> 16) & 0xff);
|
||||
blue = ((word1 >> 8) & 0xff) +
|
||||
3 * ((word3 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 22) & 0xff000000) |
|
||||
((green << 14) & 0x00ff0000) |
|
||||
((blue << 6) & 0x0000ff00);
|
||||
break;
|
||||
case 13:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = 3 * (word1 >> 24) + (word2 >> 24) +
|
||||
9 * (word3 >> 24) + 3 * (word4 >> 24);
|
||||
green = 3 * ((word1 >> 16) & 0xff) + ((word2 >> 16) & 0xff) +
|
||||
9 * ((word3 >> 16) & 0xff) + 3 * ((word4 >> 16) & 0xff);
|
||||
blue = 3 *((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff) +
|
||||
9 * ((word3 >> 8) & 0xff) + 3 * ((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 20) & 0xff000000) |
|
||||
((green << 12) & 0x00ff0000) |
|
||||
((blue << 4) & 0x0000ff00);
|
||||
break;
|
||||
case 14:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = (word1 >> 24) + (word2 >> 24) +
|
||||
3 * (word3 >> 24) + 3 * (word4 >> 24);
|
||||
green = ((word1 >> 16) & 0xff) +((word2 >> 16) & 0xff) +
|
||||
3 * ((word3 >> 16) & 0xff) + 3 * ((word4 >> 16) & 0xff);
|
||||
blue = ((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff) +
|
||||
3 * ((word3 >> 8) & 0xff) + 3 * ((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 21) & 0xff000000) |
|
||||
((green << 13) & 0x00ff0000) |
|
||||
((blue << 5) & 0x0000ff00);
|
||||
break;
|
||||
case 15:
|
||||
word1 = *pword;
|
||||
word2 = *(pword + 1);
|
||||
word3 = *(pword + wpls);
|
||||
word4 = *(pword + wpls + 1);
|
||||
red = (word1 >> 24) + 3 * (word2 >> 24) +
|
||||
3 * (word3 >> 24) + 9 * (word4 >> 24);
|
||||
green = ((word1 >> 16) & 0xff) + 3 * ((word2 >> 16) & 0xff) +
|
||||
3 * ((word3 >> 16) & 0xff) + 9 * ((word4 >> 16) & 0xff);
|
||||
blue = ((word1 >> 8) & 0xff) + 3 * ((word2 >> 8) & 0xff) +
|
||||
3 * ((word3 >> 8) & 0xff) + 9 * ((word4 >> 8) & 0xff);
|
||||
*(lined + j) = ((red << 20) & 0xff000000) |
|
||||
((green << 12) & 0x00ff0000) |
|
||||
((blue << 4) & 0x0000ff00);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "shouldn't get here\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,6 +195,43 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// testNTImage
|
||||
class NTImageAction : public Runnable {
|
||||
public:
|
||||
String name;
|
||||
PVStructure::shared_pointer pvImage;
|
||||
float angle;
|
||||
double period;
|
||||
|
||||
AtomicBoolean stopped;
|
||||
|
||||
NTImageAction(double periodHz) :
|
||||
angle(0),
|
||||
period(periodHz)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void run()
|
||||
{
|
||||
while (!stopped.get())
|
||||
{
|
||||
|
||||
{
|
||||
try {
|
||||
rotateImage(pvImage, angle);
|
||||
angle += 1;
|
||||
notifyStructureChanged(name);
|
||||
} catch (std::exception &ex) {
|
||||
std::cerr << "Unhandled exception caught in NTImageAction::run(): " << ex.what() << std::endl;
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled exception caught in NTImageAction::run()" << std::endl;
|
||||
}
|
||||
|
||||
epicsThreadSleep(period);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ChannelFindRequesterImpl : public ChannelFindRequester
|
||||
@@ -1378,7 +1415,7 @@ class MockChannel : public Channel {
|
||||
printf("=============------------------------------------!!!\n");
|
||||
*/
|
||||
}
|
||||
else if (m_name.find("testNTImage") == 0)
|
||||
else if (m_name.find("testNTImage") == 0 || m_name.find("testImage") == 0)
|
||||
{
|
||||
m_pvStructure = getPVDataCreate()->createPVStructure(makeImageStruc());
|
||||
initImage(m_pvStructure);
|
||||
@@ -1430,7 +1467,7 @@ class MockChannel : public Channel {
|
||||
String allProperties("");
|
||||
m_pvStructure = getStandardPVField()->scalar(pvDouble,allProperties);
|
||||
}
|
||||
else if (m_name == "testCounter")
|
||||
else if (m_name == "testCounter")
|
||||
{
|
||||
String allProperties("timeStamp");
|
||||
m_pvStructure = getStandardPVField()->scalar(pvInt,allProperties);
|
||||
@@ -1657,18 +1694,22 @@ class MockServerChannelProvider : public ChannelProvider,
|
||||
m_mockChannelFind(),
|
||||
m_counterChannel(),
|
||||
m_adcChannel(),
|
||||
m_scan1Hz(1.0),
|
||||
m_ntImageChannel(),
|
||||
m_scan1Hz(1.0),
|
||||
m_scan1HzThread(),
|
||||
m_adcAction(),
|
||||
m_adcThread()
|
||||
{
|
||||
m_adcThread(),
|
||||
m_imgAction(0.1),
|
||||
m_imgThread()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~MockServerChannelProvider()
|
||||
{
|
||||
m_scan1Hz.stopped.set();
|
||||
m_adcAction.stopped.set();
|
||||
}
|
||||
m_imgAction.stopped.set();
|
||||
}
|
||||
|
||||
void initialize()
|
||||
{
|
||||
@@ -1690,6 +1731,11 @@ class MockServerChannelProvider : public ChannelProvider,
|
||||
m_adcAction.adcMatrix = static_pointer_cast<MockChannel>(m_adcChannel)->m_pvStructure;
|
||||
m_adcAction.adcSim = createSimADC("testADC");
|
||||
m_adcThread.reset(new Thread("adcThread", highPriority, &m_adcAction));
|
||||
|
||||
m_ntImageChannel = MockChannel::create(chProviderPtr, cr, "testImage", "local");
|
||||
m_imgAction.name = "testImage";
|
||||
m_imgAction.pvImage = static_pointer_cast<MockChannel>(m_ntImageChannel)->m_pvStructure;
|
||||
m_imgThread.reset(new Thread("imgThread", highPriority, &m_imgAction));
|
||||
}
|
||||
|
||||
virtual epics::pvData::String getProviderName()
|
||||
@@ -1758,12 +1804,16 @@ class MockServerChannelProvider : public ChannelProvider,
|
||||
ChannelFind::shared_pointer m_mockChannelFind;
|
||||
Channel::shared_pointer m_counterChannel;
|
||||
Channel::shared_pointer m_adcChannel;
|
||||
Channel::shared_pointer m_ntImageChannel;
|
||||
|
||||
ProcessAction m_scan1Hz;
|
||||
auto_ptr<Thread> m_scan1HzThread;
|
||||
|
||||
ADCAction m_adcAction;
|
||||
auto_ptr<Thread> m_adcThread;
|
||||
|
||||
NTImageAction m_imgAction;
|
||||
auto_ptr<Thread> m_imgThread;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user