float ANoise3::Trilinear(const float & x, const float & y, const float & z) { int g0x = x>0.f ? x : x-1.f; int g0y = y>0.f ? y : y-1.f; int g0z = z>0.f ? z : z-1.f; int g1x = g0x + 1; int g1y = g0y + 1; int g1z = g0z + 1; float fx = x - g0x; float fy = y - g0y; float fz = z - g0z; float x0 = lerp(fx, SampleGrid(g0x, g0y, g0z), SampleGrid(g1x, g0y, g0z) ); float x1 = lerp(fx, SampleGrid(g0x, g1y, g0z), SampleGrid(g1x, g1y, g0z) ); float x2 = lerp(fx, SampleGrid(g0x, g0y, g1z), SampleGrid(g1x, g0y, g1z) ); float x3 = lerp(fx, SampleGrid(g0x, g1y, g1z), SampleGrid(g1x, g1y, g1z) ); float y0 = lerp(fy, x0, x1); float y1 = lerp(fy, x2, x3); return lerp(fz, y0, y1); }
CBC_QRDetectorResult* CBC_DataMatrixDetector::Detect(int32_t& e) { CFX_PtrArray* cornerPoints = m_rectangleDetector->Detect(e); BC_EXCEPTION_CHECK_ReturnValue(e, NULL); CBC_ResultPoint* pointA = (CBC_ResultPoint*)(*cornerPoints)[0]; CBC_ResultPoint* pointB = (CBC_ResultPoint*)(*cornerPoints)[1]; CBC_ResultPoint* pointC = (CBC_ResultPoint*)(*cornerPoints)[2]; CBC_ResultPoint* pointD = (CBC_ResultPoint*)(*cornerPoints)[3]; delete cornerPoints; cornerPoints = NULL; CFX_PtrArray transitions; transitions.Add(TransitionsBetween(pointA, pointB)); transitions.Add(TransitionsBetween(pointA, pointC)); transitions.Add(TransitionsBetween(pointB, pointD)); transitions.Add(TransitionsBetween(pointC, pointD)); BC_FX_PtrArray_Sort(transitions, &ResultPointsAndTransitionsComparator); delete ((CBC_ResultPointsAndTransitions*)transitions[2]); delete ((CBC_ResultPointsAndTransitions*)transitions[3]); CBC_ResultPointsAndTransitions* lSideOne = (CBC_ResultPointsAndTransitions*)transitions[0]; CBC_ResultPointsAndTransitions* lSideTwo = (CBC_ResultPointsAndTransitions*)transitions[1]; CFX_MapPtrTemplate<CBC_ResultPoint*, int32_t> pointCount; Increment(pointCount, lSideOne->GetFrom()); Increment(pointCount, lSideOne->GetTo()); Increment(pointCount, lSideTwo->GetFrom()); Increment(pointCount, lSideTwo->GetTo()); delete ((CBC_ResultPointsAndTransitions*)transitions[1]); delete ((CBC_ResultPointsAndTransitions*)transitions[0]); transitions.RemoveAll(); CBC_ResultPoint* maybeTopLeft = NULL; CBC_ResultPoint* bottomLeft = NULL; CBC_ResultPoint* maybeBottomRight = NULL; FX_POSITION itBegin = pointCount.GetStartPosition(); while (itBegin != NULL) { CBC_ResultPoint* key = 0; int32_t value = 0; pointCount.GetNextAssoc(itBegin, key, value); if (value == 2) { bottomLeft = key; } else { if (maybeBottomRight == NULL) { maybeBottomRight = key; } else { maybeTopLeft = key; } } } if (maybeTopLeft == NULL || bottomLeft == NULL || maybeBottomRight == NULL) { delete pointA; delete pointB; delete pointC; delete pointD; e = BCExceptionNotFound; return NULL; } CFX_PtrArray corners; corners.SetSize(3); corners[0] = maybeTopLeft; corners[1] = bottomLeft; corners[2] = maybeBottomRight; OrderBestPatterns(&corners); CBC_ResultPoint* bottomRight = (CBC_ResultPoint*)corners[0]; bottomLeft = (CBC_ResultPoint*)corners[1]; CBC_ResultPoint* topLeft = (CBC_ResultPoint*)corners[2]; CBC_ResultPoint* topRight = NULL; int32_t value; if (!pointCount.Lookup(pointA, value)) { topRight = pointA; } else if (!pointCount.Lookup(pointB, value)) { topRight = pointB; } else if (!pointCount.Lookup(pointC, value)) { topRight = pointC; } else { topRight = pointD; } int32_t dimensionTop = CBC_AutoPtr<CBC_ResultPointsAndTransitions>( TransitionsBetween(topLeft, topRight)) ->GetTransitions(); int32_t dimensionRight = CBC_AutoPtr<CBC_ResultPointsAndTransitions>( TransitionsBetween(bottomRight, topRight)) ->GetTransitions(); if ((dimensionTop & 0x01) == 1) { dimensionTop++; } dimensionTop += 2; if ((dimensionRight & 0x01) == 1) { dimensionRight++; } dimensionRight += 2; CBC_AutoPtr<CBC_CommonBitMatrix> bits(NULL); CBC_AutoPtr<CBC_ResultPoint> correctedTopRight(NULL); if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop) { correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>( CorrectTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight, dimensionTop, dimensionRight)); if (correctedTopRight.get() == NULL) { correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(topRight); } else { delete topRight; topRight = NULL; } dimensionTop = CBC_AutoPtr<CBC_ResultPointsAndTransitions>( TransitionsBetween(topLeft, correctedTopRight.get())) ->GetTransitions(); dimensionRight = CBC_AutoPtr<CBC_ResultPointsAndTransitions>( TransitionsBetween(bottomRight, correctedTopRight.get())) ->GetTransitions(); if ((dimensionTop & 0x01) == 1) { dimensionTop++; } if ((dimensionRight & 0x01) == 1) { dimensionRight++; } bits = CBC_AutoPtr<CBC_CommonBitMatrix>( SampleGrid(m_image, topLeft, bottomLeft, bottomRight, correctedTopRight.get(), dimensionTop, dimensionRight, e)); BC_EXCEPTION_CHECK_ReturnValue(e, NULL); } else { int32_t dimension = std::min(dimensionRight, dimensionTop); correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>( CorrectTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension)); if (correctedTopRight.get() == NULL) { correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(topRight); } else { delete topRight; topRight = NULL; } int32_t dimensionCorrected = std::max(CBC_AutoPtr<CBC_ResultPointsAndTransitions>( TransitionsBetween(topLeft, correctedTopRight.get())) ->GetTransitions(), CBC_AutoPtr<CBC_ResultPointsAndTransitions>( TransitionsBetween(bottomRight, correctedTopRight.get())) ->GetTransitions()); dimensionCorrected++; if ((dimensionCorrected & 0x01) == 1) { dimensionCorrected++; } bits = CBC_AutoPtr<CBC_CommonBitMatrix>(SampleGrid( m_image, topLeft, bottomLeft, bottomRight, correctedTopRight.get(), dimensionCorrected, dimensionCorrected, e)); BC_EXCEPTION_CHECK_ReturnValue(e, NULL); } CFX_PtrArray* result = new CFX_PtrArray; result->SetSize(4); result->Add(topLeft); result->Add(bottomLeft); result->Add(bottomRight); result->Add(correctedTopRight.release()); return new CBC_QRDetectorResult(bits.release(), result); }