const std::vector<int> getConversionCode(std::string src_encoding, std::string dst_encoding) { Encoding src_encod = getEncoding(src_encoding); Encoding dst_encod = getEncoding(dst_encoding); bool is_src_color_format = enc::isColor(src_encoding) || enc::isMono(src_encoding) || enc::isBayer(src_encoding) || (src_encoding == enc::YUV422); bool is_dst_color_format = enc::isColor(dst_encoding) || enc::isMono(dst_encoding) || enc::isBayer(dst_encoding) || (dst_encoding == enc::YUV422); bool is_num_channels_the_same = (enc::numChannels(src_encoding) == enc::numChannels(dst_encoding)); // If we have no color info in the source, we can only convert to the same format which // was resolved in the previous condition. Otherwise, fail if (!is_src_color_format) { if (is_dst_color_format) throw Exception("[" + src_encoding + "] is not a color format. but [" + dst_encoding + "] is. The conversion does not make sense"); if (!is_num_channels_the_same) throw Exception("[" + src_encoding + "] and [" + dst_encoding + "] do not have the same number of channel"); return std::vector<int>(1, SAME_FORMAT); } // If we are converting from a color type to a non color type, we can only do so if we stick // to the number of channels if (!is_dst_color_format) { if (!is_num_channels_the_same) throw Exception("[" + src_encoding + "] is a color format but [" + dst_encoding + "] " + "is not so they must have the same OpenCV type, CV_8UC3, CV16UC1 ...."); return std::vector<int>(1, SAME_FORMAT); } // If we are converting from a color type to another type, then everything is fine static const std::map<std::pair<Encoding, Encoding>, std::vector<int> > CONVERSION_CODES = getConversionCodes(); std::pair<Encoding, Encoding> key(src_encod, dst_encod); std::map<std::pair<Encoding, Encoding>, std::vector<int> >::const_iterator val = CONVERSION_CODES.find(key); if (val == CONVERSION_CODES.end()) throw Exception("Unsupported conversion from [" + src_encoding + "] to [" + dst_encoding + "]"); // And deal with depth differences if the colors are different std::vector<int> res = val->second; if ((enc::bitDepth(src_encoding) != enc::bitDepth(dst_encoding)) && (getEncoding(src_encoding) != getEncoding(dst_encoding))) res.push_back(SAME_FORMAT); return res; }
c_exp c_exp::fromLispExp(lisp_exp exp, QHash<QString, DataType> dataTypes, QHash<QString, QString> wireNames) { if (exp.isLeaf()) { if (wireNames.contains(exp.value())) { DataType dt = dataTypes.value(exp.value()); QString wireName = wireNames.value(exp.value()); return c_exp(wireName, dt); } else { bool success; exp.value().toInt(&success); if (success) { return c_exp(exp.value(), DATATYPE_INT); } else { exp.value().toFloat(&success); if (success) { return c_exp(exp.value(), DATATYPE_FLOAT); } else { return c_exp(); // error condition } } } } else { QString theOperator = exp.element(0).value(); if (theOperator == "+" || theOperator == "-") { QList<c_exp> results = evaluateArguments(exp, dataTypes, wireNames); DataType mostGeneralType = getMostGeneralType(results); DataType resultType; if (mostGeneralType.isAFP()) { resultType = DATATYPE_AFP(mostGeneralType.afpPrecision() - intLog2(results.size())); } else { resultType = mostGeneralType; } QList<QString> conversionCodes = getConversionCodes(results, resultType); QString code = conversionCodes.join(" " + theOperator + " "); return c_exp(code, resultType); } else if (theOperator == "*") { QList<c_exp > results = evaluateArguments(exp, dataTypes, wireNames); DataType mostGeneralType = getMostGeneralType(results); if (mostGeneralType.isAFP()) { QString lastCode = "(int64_t)(" + results[0].code() + ")"; DataType lastType = results[0].type(); for (int i = 1; i < results.size(); i++) { c_exp result = results[i]; if (! result.isValid()) { lastType = DataType(); } lastCode = "(" + lastCode + ") * (" + result.code() + ")"; lastCode = "(" + lastCode + ") >> 32"; int lastAFPPrecision = lastType.isAFP() ? lastType.afpPrecision() : 0; int resultAFPPrecision = result.type().isAFP() ? result.type().afpPrecision() : 0; if (lastType.isValid()) { lastType = DATATYPE_AFP(32 - ((32 - lastAFPPrecision) + (32 - resultAFPPrecision))); } } lastCode = "(int)(" + lastCode + ")"; return c_exp(lastCode, lastType); } else { DataType resultType = mostGeneralType; QList<QString> codes = getCodes(results); QString code = codes.join(" * "); return c_exp(code, resultType); } } else if (theOperator == "/") { return c_exp(); } else if (theOperator == "//") { return c_exp(); } else if (theOperator == "%") { return c_exp(); } else if (theOperator == "mod") { return c_exp(); } else if (theOperator == "if") { c_exp condResult = c_exp::fromLispExp(exp.element(1), dataTypes, wireNames); c_exp ifTrueResult = c_exp::fromLispExp(exp.element(2), dataTypes, wireNames); c_exp ifFalseResult = c_exp::fromLispExp(exp.element(3), dataTypes, wireNames); DataType resultType = moreGeneralType(ifTrueResult.type(), ifFalseResult.type()); QString code = "(" + condResult.code() + ") ? (" + ifTrueResult.conversionTo(resultType).code() + ") : (" + ifFalseResult.conversionTo(resultType).code() + ")"; return c_exp(code, resultType); } else if (theOperator == ">" || theOperator == "<" || theOperator == ">=" || theOperator == "<=" || theOperator == "==" || theOperator == "!=") { c_exp leftOperand = c_exp::fromLispExp(exp.element(1), dataTypes, wireNames); c_exp rightOperand = c_exp::fromLispExp(exp.element(2), dataTypes, wireNames); DataType resultType = moreGeneralType(leftOperand.type(), rightOperand.type()); QString code = "(" + leftOperand.conversionTo(resultType).code() + ") " + theOperator + " (" + rightOperand.conversionTo(resultType).code() + ")"; return c_exp(code, resultType); } else if (theOperator == "sqrt") { c_exp operand = c_exp::fromLispExp(exp.element(1), dataTypes, wireNames); QString code = "sqrt(" + operand.code() + ")"; return c_exp(code, DATATYPE_FLOAT); } else if (theOperator == "read_adc") { QString code = "((int)read_adc(" + c_exp::fromLispExp(exp.element(1), dataTypes, wireNames).conversionTo(DATATYPE_INT).code() + ") << 16)"; return c_exp(code, DATATYPE_AFP(27)); } else { return c_exp(); // error condition } } }