639 lines
25 KiB
C++
639 lines
25 KiB
C++
#include "epicsv4Grayscale.h"
|
|
|
|
epics::pvData::StructureConstPtr makeVariantArrayStruc()
|
|
{
|
|
FieldConstPtrArray vaFields;
|
|
StringArray vaNames;
|
|
|
|
vaFields.push_back(getFieldCreate()->createScalar(epics::pvData::pvInt));
|
|
vaNames.push_back("dataType");
|
|
|
|
vaFields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvInt));
|
|
vaNames.push_back("value");
|
|
|
|
epics::pvData::StructureConstPtr varrayStruc = getFieldCreate()->createStructure("uri:ev4:nt/2012/pwd:NTVariantArray", vaNames, vaFields);
|
|
|
|
return varrayStruc;
|
|
}
|
|
|
|
epics::pvData::StructureConstPtr makeImageStruc()
|
|
{
|
|
static epics::pvData::StructureConstPtr imageStruc;
|
|
|
|
if (imageStruc == NULL)
|
|
{
|
|
FieldConstPtrArray fields;
|
|
StringArray names;
|
|
|
|
// Array part
|
|
fields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvByte));
|
|
names.push_back("value");
|
|
|
|
fields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvInt));
|
|
names.push_back("dim");
|
|
|
|
// Image part
|
|
fields.push_back(getFieldCreate()->createScalar(epics::pvData::pvInt));
|
|
names.push_back("colorMode");
|
|
|
|
fields.push_back(getFieldCreate()->createScalar(epics::pvData::pvInt));
|
|
names.push_back("bayerPattern");
|
|
|
|
fields.push_back(getFieldCreate()->createScalar(epics::pvData::pvString));
|
|
names.push_back("fourcc");
|
|
|
|
fields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvInt));
|
|
names.push_back("offset");
|
|
|
|
fields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvInt));
|
|
names.push_back("binning");
|
|
|
|
fields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvInt));
|
|
names.push_back("reverse");
|
|
|
|
fields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvInt));
|
|
names.push_back("fullDim");
|
|
|
|
|
|
// Metadata part
|
|
fields.push_back(getFieldCreate()->createScalar(epics::pvData::pvInt));
|
|
names.push_back("uniqueId");
|
|
|
|
fields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvInt));
|
|
names.push_back("attributeSourceTypes");
|
|
|
|
fields.push_back(getFieldCreate()->createScalarArray(epics::pvData::pvString));
|
|
names.push_back("attributeSources");
|
|
|
|
fields.push_back(getFieldCreate()->createStructureArray(makeVariantArrayStruc()));
|
|
names.push_back("attributes");
|
|
|
|
imageStruc = getFieldCreate()->createStructure("uri:ev4:nt/2012/pwd:NTImage", names, fields);
|
|
}
|
|
|
|
|
|
return imageStruc;
|
|
}
|
|
|
|
void setImageArrayValues(PVStructure::shared_pointer const & imagePV)
|
|
{
|
|
String id = imagePV->getStructure()->getID();
|
|
PVByteArrayPtr pvField = static_pointer_cast<PVByteArray>(imagePV->getSubField("value"));
|
|
|
|
size_t dataSize = epicsv4_raw_size;
|
|
pvField->setCapacity(dataSize);
|
|
const int8_t *data = epicsv4_raw;
|
|
pvField->put(0, dataSize, data, 0);
|
|
|
|
PVIntArrayPtr dimField = static_pointer_cast<PVIntArray>(
|
|
imagePV->getScalarArrayField(String("dim"), pvInt));
|
|
dimField->setCapacity(2);
|
|
const int32_t *dim = epicsv4_raw_dim;
|
|
dimField->put(0, 2, dim, 0);
|
|
}
|
|
|
|
|
|
void setImageImageValues(PVStructure::shared_pointer const & imagePV)
|
|
{
|
|
PVIntArrayPtr offsetField = static_pointer_cast<PVIntArray>(
|
|
imagePV->getScalarArrayField(String("offset"), pvInt));
|
|
offsetField->setCapacity(2);
|
|
int32_t offsets[] = { 0, 0 };
|
|
offsetField->put(0, 2, offsets, 0);
|
|
|
|
PVIntArrayPtr binningField = static_pointer_cast<PVIntArray>(
|
|
imagePV->getScalarArrayField(String("binning"), pvInt));
|
|
binningField->setCapacity(2);
|
|
int32_t binnings[] = { 1, 1 };
|
|
binningField->put(0, 2, binnings, 0);
|
|
|
|
PVIntArrayPtr reverseField = static_pointer_cast<PVIntArray>(
|
|
imagePV->getScalarArrayField(String("reverse"), pvInt));
|
|
reverseField->setCapacity(2);
|
|
int32_t reverses[] = { 0, 0 };
|
|
reverseField->put(0, 2, reverses, 0);
|
|
|
|
PVIntArrayPtr fullDimField = static_pointer_cast<PVIntArray>(
|
|
imagePV->getScalarArrayField(String("fullDim"), pvInt));
|
|
fullDimField->setCapacity(2);
|
|
const int32_t *fullDim = epicsv4_raw_dim;
|
|
fullDimField->put(0, 2, fullDim, 0);
|
|
|
|
}
|
|
|
|
|
|
void setImageUniqueId(PVStructure::shared_pointer const & imagePV)
|
|
{
|
|
PVIntPtr uniqueIdField = imagePV->getIntField(String("uniqueId"));
|
|
uniqueIdField->put(0);
|
|
}
|
|
|
|
void setImageMetadataValues(PVStructure::shared_pointer const & imagePV)
|
|
{
|
|
setImageUniqueId(imagePV);
|
|
}
|
|
|
|
|
|
void initImage(PVStructure::shared_pointer const & imagePV)
|
|
{
|
|
setImageArrayValues(imagePV);
|
|
setImageImageValues(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;
|
|
}
|