diff --git a/pvtoolsSrc/eget.cpp b/pvtoolsSrc/eget.cpp index a609fcb..40ecf78 100644 --- a/pvtoolsSrc/eget.cpp +++ b/pvtoolsSrc/eget.cpp @@ -682,76 +682,107 @@ void formatNTURI(std::ostream& o, PVStructurePtr const & pvStruct) } -void formatNTImage(std::ostream& /*o*/, PVStructurePtr const & pvStruct) +void formatNTNDArray(std::ostream& /*o*/, PVStructurePtr const & pvStruct) { - PVIntPtr colorMode = pvStruct->getIntField("colorMode"); - if (colorMode.get() == 0) + + PVUnion::shared_pointer pvUnion = pvStruct->getSubField("value"); + if (pvUnion.get() == 0) { - std::cerr << "no int 'colorMode' field in NTImage" << std::endl; - return; - } - int32 cm = colorMode->get(); - if (cm != 0 && cm != 1 && cm != 2) - { - std::cerr << "unsupported image 'colorMode', only {0,1,2} modes are supported" << std::endl; + std::cerr << "no 'value' union field in NTNDArray" << std::endl; return; } - PVScalarArrayPtr value = dynamic_pointer_cast(pvStruct->getSubField("value")); + PVScalarArray::shared_pointer value = pvUnion->get(); if (value.get() == 0) { - std::cerr << "no scalar array 'value' field in NTImage" << std::endl; + std::cerr << "'value' union field in given NTNDArray does not hold scalar array value" << std::endl; return; } + // undefined + int32 cm = -1; + + PVStructureArray::shared_pointer pvAttributes = pvStruct->getSubField("attribute"); + PVStructureArray::const_svector attributes(pvAttributes->view()); + + for (PVStructureArray::const_svector::const_iterator iter = attributes.begin(); + iter != attributes.end(); + iter++) + { + PVStructure::shared_pointer attribute = *iter; + PVString::shared_pointer pvName = attribute->getSubField("name"); + if (pvName && pvName->get() == "ColorMode") + { + PVInt::shared_pointer pvCM = attribute->getSubField("value")->get(); + if (!pvCM) + break; + + cm = pvCM->get(); + break; + } + } + + if (cm == -1) + { + std::cerr << "no PVInt 'ColorMode' attribute in NTNDArray" << std::endl; + return; + } + + if (cm != 0 && cm != 1 && cm != 2) + { + std::cerr << "unsupported 'ColorMode', only {0,1,2} modes are supported" << std::endl; + return; + } + + int32 rows, cols; - PVIntArrayPtr dim = dynamic_pointer_cast(pvStruct->getScalarArrayField("dim", pvInt)); + PVStructureArray::shared_pointer dim = pvStruct->getSubField("dimension"); if (dim.get() == 0) { - std::cerr << "no int[] 'dim' field in NTImage" << std::endl; + std::cerr << "no 'dimension' structure array field in NTNDArray" << std::endl; return; } - + // dim[] = { rows, columns } or // dim[] = { 3, rows, columns } - PVIntArray::const_svector data = dim->view(); + PVStructureArray::const_svector data = dim->view(); size_t dims = dim->getLength(); size_t imageSize; if ((cm == 0 || cm == 1) && dims == 2) { - cols = data[0]; - rows = data[1]; + cols = data[0]->getSubField("size")->get(); + rows = data[1]->getSubField("size")->get(); imageSize = cols * rows; } else if (cm == 2 && dims == 3) { - cols = data[1]; - rows = data[2]; + cols = data[0]->getSubField("size")->get(); + rows = data[1]->getSubField("size")->get(); imageSize = cols * rows * 3; } else { - std::cerr << "malformed NTImage, dim[] is invalid for specified color mode" << std::endl; + std::cerr << "malformed NTNDArray, dimension[] is invalid for specified color mode" << std::endl; return; } if (rows <= 0 || cols <= 0) { - std::cerr << "malformed NTImage, dim[] must contain elements > 0" << std::endl; + std::cerr << "malformed NTNDArray, dimension[] gives negative size" << std::endl; return; } PVByteArrayPtr array = dynamic_pointer_cast(value); if (array.get() == 0) { - std::cerr << "currently only byte[] value field is supported" << std::endl; + std::cerr << "currently only byte[] value is supported" << std::endl; return; } if (array->getLength() != imageSize) { - std::cerr << "byte[] length does not match expected image size (" << + std::cerr << "value array length does not match expected image size (" << array->getLength() << " != " << imageSize << ")" << std::endl; return; } @@ -792,7 +823,7 @@ void formatNTImage(std::ostream& /*o*/, PVStructurePtr const & pvStruct) } else { - // grayscale + // monochrome fprintf(gnuplotPipe, "set palette grey\n"); fprintf(gnuplotPipe, "set cbrange [0:255]\n"); @@ -822,7 +853,7 @@ void initializeNTFormatterLUT() ntFormatterLUT["uri:ev4:nt/2012/pwd:NTAny"] = formatNTAny; ntFormatterLUT["uri:ev4:nt/2012/pwd:NTNameValue"] = formatNTNameValue; ntFormatterLUT["uri:ev4:nt/2012/pwd:NTURI"] = formatNTURI; - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTImage"] = formatNTImage; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTNDArray"] = formatNTNDArray; } void formatNT(std::ostream& o, PVFieldPtr const & pv) diff --git a/testApp/remote/testNTImage.cpp b/testApp/remote/testNTImage.cpp index ce64ae8..bd93d0b 100644 --- a/testApp/remote/testNTImage.cpp +++ b/testApp/remote/testNTImage.cpp @@ -32,7 +32,7 @@ epics::pvData::StructureConstPtr createNTNDArrayStructure() StructureConstPtr attributeStruc = fb->setId("uri:ev4:nt/2012/pwd:NTAttribute")-> add("name", pvString)-> add("value", getFieldCreate()->createVariantUnion())-> - add("description", pvString)-> + add("descriptor", pvString)-> add("sourceType", pvInt)-> add("source", pvString)-> createStructure(); @@ -40,9 +40,9 @@ epics::pvData::StructureConstPtr createNTNDArrayStructure() ntndArrayStructure = fb->setId("uri:ev4:nt/2012/pwd:NTNDArray")-> add("value", valueType)-> + add("codec", codecStruc)-> add("compressedSize", pvLong)-> add("uncompressedSize", pvLong)-> - add("codec", codecStruc)-> addArray("dimension", dimensionStruc)-> add("uniqueId", pvInt)-> add("dataTimeStamp", standardField->timeStamp())-> @@ -108,28 +108,36 @@ void setNTNDArrayValue( void setNTNDArrayData( PVStructure::shared_pointer const & imagePV, - const string & codec + const string & codec, + int32 colorMode ) { imagePV->getSubField("codec.name")->put(codec); imagePV->getSubField("uniqueId")->put(0); -} -/* -//d) Attributes - structure[] attribute - structure NTAttribute - string name - any value - string description - int sourceType - string source -*/ + PVStructureArray::shared_pointer pvAttributes = imagePV->getSubField("attribute"); + PVStructureArray::svector attributes(pvAttributes->reuse()); + + PVStructure::shared_pointer attribute = + getPVDataCreate()->createPVStructure(pvAttributes->getStructureArray()->getStructure()); + attribute->getSubField("name")->put("ColorMode"); + PVInt::shared_pointer pvColorMode = getPVDataCreate()->createPVScalar(); + pvColorMode->put(colorMode); + attributes.push_back(attribute); + pvAttributes->replace(freeze(attributes)); + attribute->getSubField("value")->set(pvColorMode); + attribute->getSubField("descriptor")->put("Color mode"); + attribute->getSubField("sourceType")->put(0); + attribute->getSubField("source")->put(""); + + +} void initImage( PVStructure::shared_pointer const & imagePV, const string & codec, + int32 colorMode, const size_t raw_dim_size, const int32_t* raw_dim, const size_t raw_size, @@ -137,13 +145,13 @@ void initImage( ) { setNTNDArrayValue(imagePV, raw_dim_size, raw_dim, raw_size, raw); - setNTNDArrayData(imagePV, codec); + setNTNDArrayData(imagePV, codec, colorMode); } void initImageEPICSv4GrayscaleLogo(PVStructure::shared_pointer const & imagePV) { setNTNDArrayValue(imagePV, 2, epicsv4_raw_dim, epicsv4_raw_size, epicsv4_raw); - setNTNDArrayData(imagePV, "grayscale"); + setNTNDArrayData(imagePV, "", 0 /* NDColorModeMono=0 */); } void rotateImage(PVStructure::shared_pointer const & imagePV, const int8_t* originalImage, float deg) @@ -152,7 +160,7 @@ void rotateImage(PVStructure::shared_pointer const & imagePV, const int8_t* orig PVStructureArrayPtr dim = imagePV->getSubField("dimension"); PVStructureArray::const_svector data = dim->view(); - // { x, y } + // 2d NTNDArray - { x, y } int32 cols = data[0]->getSubField("size")->get(); int32 rows = data[1]->getSubField("size")->get(); diff --git a/testApp/remote/testServer.cpp b/testApp/remote/testServer.cpp index 9c98f94..0151372 100644 --- a/testApp/remote/testServer.cpp +++ b/testApp/remote/testServer.cpp @@ -1467,12 +1467,12 @@ public: if (isRGB) { const int32_t dim[] = { 3, wv, hv }; - initImage(m_pvStructure, "RGB", 3, dim, fileSize, 0); + initImage(m_pvStructure, "", 2 /* NDColorModeRGB1=2 */, 3, dim, fileSize, 0); } else { const int32_t dim[] = { wv, hv }; - initImage(m_pvStructure, "grayscale", 2, dim, fileSize, 0); + initImage(m_pvStructure, "", 0 /* NDColorModeMono=0 */, 2, dim, fileSize, 0); } PVByteArrayPtr value = std::tr1::dynamic_pointer_cast(m_pvStructure->getSubField("value"));