Exemple #1
0
void NTNDArrayConverter::fromAttributes (NDArray *src)
{
    PVStructureArrayPtr dest(m_array->getAttribute());
    NDAttributeList *srcList = src->pAttributeList;
    NDAttribute *attr = NULL;
    StructureConstPtr structure(dest->getStructureArray()->getStructure());
    PVStructureArray::svector destVec(dest->reuse());

    destVec.resize(srcList->count());

    size_t i = 0;
    while((attr = srcList->next(attr)))
    {
        if(!destVec[i].get() || !destVec[i].unique())
            destVec[i] = PVDC->createPVStructure(structure);

        PVStructurePtr pvAttr(destVec[i]);

        pvAttr->getSubField<PVString>("name")->put(attr->getName());
        pvAttr->getSubField<PVString>("descriptor")->put(attr->getDescription());
        pvAttr->getSubField<PVString>("source")->put(attr->getSource());

        NDAttrSource_t sourceType;
        attr->getSourceInfo(&sourceType);
        pvAttr->getSubField<PVInt>("sourceType")->put(sourceType);

        switch(attr->getDataType())
        {
        case NDAttrInt8:      fromAttribute <PVByte,   int8_t>  (pvAttr, attr); break;
        case NDAttrUInt8:     fromAttribute <PVUByte,  uint8_t> (pvAttr, attr); break;
        case NDAttrInt16:     fromAttribute <PVShort,  int16_t> (pvAttr, attr); break;
        case NDAttrUInt16:    fromAttribute <PVUShort, uint16_t>(pvAttr, attr); break;
        case NDAttrInt32:     fromAttribute <PVInt,    int32_t> (pvAttr, attr); break;
        case NDAttrUInt32:    fromAttribute <PVUInt,   uint32_t>(pvAttr, attr); break;
        case NDAttrFloat32:   fromAttribute <PVFloat,  float>   (pvAttr, attr); break;
        case NDAttrFloat64:   fromAttribute <PVDouble, double>  (pvAttr, attr); break;
        case NDAttrString:    fromStringAttribute(pvAttr, attr); break;
        case NDAttrUndefined: fromUndefinedAttribute(pvAttr); break;
        default:              throw std::runtime_error("invalid attribute data type");
        }

        ++i;
    }

    dest->replace(freeze(destVec));
}
Exemple #2
0
/** Opens a TIFF file.
  * \param[in] fileName The name of the file to open.
  * \param[in] openMode Mask defining how the file should be opened; bits are 
  *            NDFileModeRead, NDFileModeWrite, NDFileModeAppend, NDFileModeMultiple
  * \param[in] pArray A pointer to an NDArray; this is used to determine the array and attribute properties.
  */
asynStatus NDFileTIFF::openFile(const char *fileName, NDFileOpenMode_t openMode, NDArray *pArray)
{
    /* When we create TIFF variables and dimensions, we get back an
     * ID for each one. */
    static const char *functionName = "openFile";
    size_t sizeX, sizeY, rowsPerStrip;
    int bitsPerSample=8, sampleFormat=SAMPLEFORMAT_INT, samplesPerPixel, photoMetric, planarConfig;
    int colorMode=NDColorModeMono;
    NDAttribute *pAttribute = NULL;
    char tagString[MAX_ATTRIBUTE_STRING_SIZE] = {0};
    char attrString[MAX_ATTRIBUTE_STRING_SIZE] = {0};

    /* We don't support reading yet */
    if (openMode & NDFileModeRead) return(asynError);

    /* We don't support opening an existing file for appending yet */
    if (openMode & NDFileModeAppend) return(asynError);

   /* Create the file. */
    if ((this->output = TIFFOpen(fileName, "w")) == NULL ) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
        "%s:%s error opening file %s\n",
        driverName, functionName, fileName);
        return(asynError);
    }
    /* We do some special treatment based on colorMode */
    pAttribute = pArray->pAttributeList->find("ColorMode");
    if (pAttribute) pAttribute->getValue(NDAttrInt32, &colorMode);

    switch (pArray->dataType) {
        case NDInt8:
            sampleFormat = SAMPLEFORMAT_INT;
            bitsPerSample = 8;
            break;
        case NDUInt8:
            sampleFormat = SAMPLEFORMAT_UINT;
            bitsPerSample = 8;
            break;
        case NDInt16:
            sampleFormat = SAMPLEFORMAT_INT;
            bitsPerSample = 16;
            break;
        case NDUInt16:
            sampleFormat = SAMPLEFORMAT_UINT;
            bitsPerSample = 16;
            break;
        case NDInt32:
            sampleFormat = SAMPLEFORMAT_INT;
            bitsPerSample = 32;
            break;
        case NDUInt32:
            sampleFormat = SAMPLEFORMAT_UINT;
            bitsPerSample = 32;
            break;
        case NDFloat32:
            sampleFormat = SAMPLEFORMAT_IEEEFP;
            bitsPerSample = 32;
            break;
        case NDFloat64:
            sampleFormat = SAMPLEFORMAT_IEEEFP;
            bitsPerSample = 64;
            break;
    }
    if (pArray->ndims == 2) {
        sizeX = pArray->dims[0].size;
        sizeY = pArray->dims[1].size;
        rowsPerStrip = sizeY;
        samplesPerPixel = 1;
        photoMetric = PHOTOMETRIC_MINISBLACK;
        planarConfig = PLANARCONFIG_CONTIG;
        this->colorMode = NDColorModeMono;
    } else if ((pArray->ndims == 3) && (pArray->dims[0].size == 3) && (colorMode == NDColorModeRGB1)) {
        sizeX = pArray->dims[1].size;
        sizeY = pArray->dims[2].size;
        rowsPerStrip = sizeY;
        samplesPerPixel = 3;
        photoMetric = PHOTOMETRIC_RGB;
        planarConfig = PLANARCONFIG_CONTIG;
        this->colorMode = NDColorModeRGB1;
    } else if ((pArray->ndims == 3) && (pArray->dims[1].size == 3) && (colorMode == NDColorModeRGB2)) {
        sizeX = pArray->dims[0].size;
        sizeY = pArray->dims[2].size;
        rowsPerStrip = 1;
        samplesPerPixel = 3;
        photoMetric = PHOTOMETRIC_RGB;
        planarConfig = PLANARCONFIG_SEPARATE;
        this->colorMode = NDColorModeRGB2;
    } else if ((pArray->ndims == 3) && (pArray->dims[2].size == 3) && (colorMode == NDColorModeRGB3)) {
        sizeX = pArray->dims[0].size;
        sizeY = pArray->dims[1].size;
        rowsPerStrip = sizeY;
        samplesPerPixel = 3;
        photoMetric = PHOTOMETRIC_RGB;
        planarConfig = PLANARCONFIG_SEPARATE;
        this->colorMode = NDColorModeRGB3;
    } else {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
            "%s:%s: unsupported array structure\n",
            driverName, functionName);
        return(asynError);
    }

    /* this is in the unallocated 'reusable' range */
    static const int TIFFTAG_NDTIMESTAMP    = 65000;
    static const int TIFFTAG_UNIQUEID       = 65001;
    static const int TIFFTAG_EPICSTSSEC     = 65002;
    static const int TIFFTAG_EPICSTSNSEC    = 65003;
    static const TIFFFieldInfo NDTimeStampFI = {
        TIFFTAG_NDTIMESTAMP,1,1,TIFF_DOUBLE,FIELD_CUSTOM,1,0,(char *)"NDTimeStamp"
    };
    static const TIFFFieldInfo NDUniqueIdFI = {
        TIFFTAG_UNIQUEID,1,1,TIFF_LONG,FIELD_CUSTOM,1,0,(char *)"NDUniqueId"
    };
    static const TIFFFieldInfo EPICSTSSecFI = {
        TIFFTAG_EPICSTSSEC,1,1,TIFF_LONG,FIELD_CUSTOM,1,0,(char *)"EPICSTSSec"
    };
    static const TIFFFieldInfo EPICSTSNsecFI = {
        TIFFTAG_EPICSTSNSEC,1,1,TIFF_LONG,FIELD_CUSTOM,1,0,(char *)"EPICSTSNsec"
    };
    TIFFMergeFieldInfo(output, &NDTimeStampFI, 1);
    TIFFMergeFieldInfo(output, &NDUniqueIdFI, 1);
    TIFFMergeFieldInfo(output, &EPICSTSSecFI, 1);
    TIFFMergeFieldInfo(output, &EPICSTSNsecFI, 1);
    TIFFSetField(this->output, TIFFTAG_NDTIMESTAMP, pArray->timeStamp);
    TIFFSetField(this->output, TIFFTAG_UNIQUEID, pArray->uniqueId);
    TIFFSetField(this->output, TIFFTAG_EPICSTSSEC, pArray->epicsTS.secPastEpoch);
    TIFFSetField(this->output, TIFFTAG_EPICSTSNSEC, pArray->epicsTS.nsec);
    TIFFSetField(this->output, TIFFTAG_BITSPERSAMPLE, bitsPerSample);
    TIFFSetField(this->output, TIFFTAG_SAMPLEFORMAT, sampleFormat);
    TIFFSetField(this->output, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
    TIFFSetField(this->output, TIFFTAG_PHOTOMETRIC, photoMetric);
    TIFFSetField(this->output, TIFFTAG_PLANARCONFIG, planarConfig);
    TIFFSetField(this->output, TIFFTAG_IMAGEWIDTH, (epicsUInt32)sizeX);
    TIFFSetField(this->output, TIFFTAG_IMAGELENGTH, (epicsUInt32)sizeY);
    TIFFSetField(this->output, TIFFTAG_ROWSPERSTRIP, (epicsUInt32)rowsPerStrip);
    
    this->pFileAttributes->clear();
    this->getAttributes(this->pFileAttributes);
    pArray->pAttributeList->copy(this->pFileAttributes);
 
    pAttribute = this->pFileAttributes->find("Model");
    if (pAttribute) {
        pAttribute->getValue(NDAttrString, tagString);
        TIFFSetField(this->output, TIFFTAG_MODEL, tagString);
    } else {
        TIFFSetField(this->output, TIFFTAG_MODEL, "Unknown");
    }
    
    pAttribute = this->pFileAttributes->find("Manufacturer");
    if (pAttribute) {
        pAttribute->getValue(NDAttrString, tagString);
        TIFFSetField(this->output, TIFFTAG_MAKE, tagString);
    } else {
        TIFFSetField(this->output, TIFFTAG_MAKE, "Unknown");
    }

    TIFFSetField(this->output, TIFFTAG_SOFTWARE, "EPICS areaDetector");

    int count = 0;
    int tagId = TIFFTAG_START_;
   
    numAttributes_ = this->pFileAttributes->count();
    asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
        "%s:%s this->pFileAttributes->count(): %d\n",
        driverName, functionName, numAttributes_);

    fieldInfo_ = (TIFFFieldInfo**) malloc(numAttributes_ * sizeof(TIFFFieldInfo *));
    if (fieldInfo_ == NULL) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
            "%s:%s error, fieldInfo_ malloc failed. file: %s\n",
            driverName, functionName, fileName);
        return asynError;
    }
    for (int i=0; i<numAttributes_; ++i) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
            "%s:%s Initializing %d fieldInfo_ entry.\n",
            driverName, functionName, i);
        fieldInfo_[i] = NULL;
    }
    
    asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
        "%s:%s Looping over attributes...\n",
        driverName, functionName);

    pAttribute = this->pFileAttributes->next(NULL);
    while (pAttribute) {
        const char *attributeName = pAttribute->getName();
        //const char *attributeDescription = pAttribute->getDescription();
        const char *attributeSource = pAttribute->getSource();

        asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
          "%s:%s : attribute: %s, source: %s\n",
          driverName, functionName, attributeName, attributeSource);

        NDAttrDataType_t attrDataType;
        size_t attrSize;
        NDAttrValue value;
        pAttribute->getValueInfo(&attrDataType, &attrSize);
        memset(tagString, 0, MAX_ATTRIBUTE_STRING_SIZE);

        switch (attrDataType) {
            case NDAttrInt8:
            case NDAttrUInt8:
            case NDAttrInt16:
            case NDAttrUInt16:
            case NDAttrInt32:
            case NDAttrUInt32: {
                pAttribute->getValue(attrDataType, &value.i32);
                epicsSnprintf(tagString, MAX_ATTRIBUTE_STRING_SIZE, "%s:%d", attributeName, value.i32);
                break;
            }
            case NDAttrFloat32: {
                pAttribute->getValue(attrDataType, &value.f32);
                epicsSnprintf(tagString, MAX_ATTRIBUTE_STRING_SIZE, "%s:%f", attributeName, value.f32);
                break;
            }
            case NDAttrFloat64: {
                pAttribute->getValue(attrDataType, &value.f64);
                epicsSnprintf(tagString, MAX_ATTRIBUTE_STRING_SIZE, "%s:%f", attributeName, value.f64);
                break;
            }
            case NDAttrString: {
                memset(attrString, 0, MAX_ATTRIBUTE_STRING_SIZE);
                pAttribute->getValue(attrDataType, attrString, MAX_ATTRIBUTE_STRING_SIZE);
                epicsSnprintf(tagString, MAX_ATTRIBUTE_STRING_SIZE, "%s:%s", attributeName, attrString);
                break;
            }
            case NDAttrUndefined:
                break;
            default:
                asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
                          "%s:%s error, unknown attrDataType=%d\n",
                          driverName, functionName, attrDataType);
                return asynError;
                break;
        }

        if (attrDataType != NDAttrUndefined) {
            asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
                "%s:%s : tagId: %d, tagString: %s\n",
                  driverName, functionName, tagId, tagString);
            fieldInfo_[count] = (TIFFFieldInfo*) malloc(sizeof(TIFFFieldInfo));
            populateAsciiFieldInfo(fieldInfo_[count], tagId, attributeName);
            TIFFMergeFieldInfo(output, fieldInfo_[count], 1);
            TIFFSetField(this->output, tagId, tagString);
            ++count;
            ++tagId;
            if ((tagId == TIFFTAG_END_) || (count > numAttributes_)) {
                asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
                    "%s:%s error, Too many tags/attributes for file. tagId: %d, count: %d\n",
                    driverName, functionName, tagId, count);
                break;
            }
        }
        pAttribute = this->pFileAttributes->next(pAttribute);
    }
    
    return(asynSuccess);
}