|
|
@ -13,25 +13,28 @@ |
|
|
|
#import "CvType.h" |
|
|
|
#import "CvType.h" |
|
|
|
#import "CVObjcUtil.h" |
|
|
|
#import "CVObjcUtil.h" |
|
|
|
|
|
|
|
|
|
|
|
// return true if we have reached the final index |
|
|
|
static int idx2Offset(cv::Mat* mat, std::vector<int>& indices) { |
|
|
|
static bool incIdx(cv::Mat* mat, std::vector<int>& indices) { |
|
|
|
int offset = indices[0]; |
|
|
|
for (int dim = mat->dims-1; dim>=0; dim--) { |
|
|
|
for (int dim=1; dim < mat->dims; dim++) { |
|
|
|
indices[dim] = (indices[dim] + 1) % mat->size[dim]; |
|
|
|
offset = offset*mat->size[dim] + indices[dim]; |
|
|
|
if (indices[dim] != 0) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return offset; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// returns true if final index was reached |
|
|
|
static void offset2Idx(cv::Mat* mat, size_t offset, std::vector<int>& indices) { |
|
|
|
static bool updateIdx(cv::Mat* mat, std::vector<int>& indices, int inc) { |
|
|
|
for (int dim=mat->dims-1; dim>=0; dim--) { |
|
|
|
for (int index = 0; index < inc; index++) { |
|
|
|
indices[dim] = offset % mat->size[dim]; |
|
|
|
if (incIdx(mat, indices)) { |
|
|
|
offset = (offset - indices[dim]) / mat->size[dim]; |
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// returns true if final index was reached |
|
|
|
|
|
|
|
static bool updateIdx(cv::Mat* mat, std::vector<int>& indices, size_t inc) { |
|
|
|
|
|
|
|
size_t currentOffset = idx2Offset(mat, indices); |
|
|
|
|
|
|
|
size_t newOffset = currentOffset + inc; |
|
|
|
|
|
|
|
bool reachedEnd = newOffset>=(size_t)mat->total(); |
|
|
|
|
|
|
|
offset2Idx(mat, reachedEnd?0:newOffset, indices); |
|
|
|
|
|
|
|
return reachedEnd; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@implementation Mat { |
|
|
|
@implementation Mat { |
|
|
@ -724,22 +727,31 @@ template<typename T> int getData(NSArray<NSNumber*>* indices, cv::Mat* mat, int |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int arrayAvailable = count; |
|
|
|
int arrayAvailable = count; |
|
|
|
|
|
|
|
size_t countBytes = count * sizeof(T); |
|
|
|
|
|
|
|
size_t remainingBytes = (size_t)(mat->total() - idx2Offset(mat, tempIndices))*mat->elemSize(); |
|
|
|
|
|
|
|
countBytes = (countBytes>remainingBytes)?remainingBytes:countBytes; |
|
|
|
|
|
|
|
int result = (int)countBytes; |
|
|
|
int matAvailable = getMatAvailable(mat, tempIndices); |
|
|
|
int matAvailable = getMatAvailable(mat, tempIndices); |
|
|
|
int available = MIN(arrayAvailable, matAvailable); |
|
|
|
int available = MIN(arrayAvailable, matAvailable); |
|
|
|
int result = (int)(available * mat->elemSize() / mat->channels()); |
|
|
|
|
|
|
|
if (mat->isContinuous()) { |
|
|
|
if (mat->isContinuous()) { |
|
|
|
memcpy(tBuffer, mat->ptr(tempIndices.data()), available * sizeof(T)); |
|
|
|
memcpy(tBuffer, mat->ptr(tempIndices.data()), available * sizeof(T)); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
int copyOffset = 0; |
|
|
|
char* buff = (char*)tBuffer; |
|
|
|
int copyCount = MIN((mat->size[mat->dims - 1] - tempIndices[mat->dims - 1]) * mat->channels(), available); |
|
|
|
size_t blockSize = mat->size[mat->dims-1] * mat->elemSize(); |
|
|
|
while (available > 0) { |
|
|
|
size_t firstPartialBlockSize = (mat->size[mat->dims-1] - tempIndices[mat->dims-1]) * mat->step[mat->dims-1]; |
|
|
|
memcpy(tBuffer + copyOffset, mat->ptr(tempIndices.data()), copyCount * sizeof(T)); |
|
|
|
for (int dim=mat->dims-2; dim>=0 && blockSize == mat->step[dim]; dim--) { |
|
|
|
if (updateIdx(mat, tempIndices, copyCount / mat->channels())) { |
|
|
|
blockSize *= mat->size[dim]; |
|
|
|
break; |
|
|
|
firstPartialBlockSize += (mat->size[dim] - (tempIndices[dim]+1)) * mat->step[dim]; |
|
|
|
} |
|
|
|
} |
|
|
|
available -= copyCount; |
|
|
|
size_t copyCount = (countBytes<firstPartialBlockSize)?countBytes:firstPartialBlockSize; |
|
|
|
copyOffset += copyCount * sizeof(T); |
|
|
|
uchar* data = mat->ptr(tempIndices.data()); |
|
|
|
copyCount = MIN(mat->size[mat->dims-1] * mat->channels(), available); |
|
|
|
while(countBytes>0) { |
|
|
|
|
|
|
|
memcpy(buff, data, copyCount); |
|
|
|
|
|
|
|
updateIdx(mat, tempIndices, copyCount / mat->elemSize()); |
|
|
|
|
|
|
|
countBytes -= copyCount; |
|
|
|
|
|
|
|
buff += copyCount; |
|
|
|
|
|
|
|
copyCount = countBytes<blockSize?countBytes:blockSize; |
|
|
|
|
|
|
|
data = mat->ptr(tempIndices.data()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
return result; |
|
|
@ -817,22 +829,31 @@ template<typename T> int putData(NSArray<NSNumber*>* indices, cv::Mat* mat, int |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int arrayAvailable = count; |
|
|
|
int arrayAvailable = count; |
|
|
|
|
|
|
|
size_t countBytes = count * sizeof(T); |
|
|
|
|
|
|
|
size_t remainingBytes = (size_t)(mat->total() - idx2Offset(mat, tempIndices))*mat->elemSize(); |
|
|
|
|
|
|
|
countBytes = (countBytes>remainingBytes)?remainingBytes:countBytes; |
|
|
|
|
|
|
|
int result = (int)countBytes; |
|
|
|
int matAvailable = getMatAvailable(mat, tempIndices); |
|
|
|
int matAvailable = getMatAvailable(mat, tempIndices); |
|
|
|
int available = MIN(arrayAvailable, matAvailable); |
|
|
|
int available = MIN(arrayAvailable, matAvailable); |
|
|
|
int result = (int)(available * mat->elemSize() / mat->channels()); |
|
|
|
|
|
|
|
if (mat->isContinuous()) { |
|
|
|
if (mat->isContinuous()) { |
|
|
|
memcpy(mat->ptr(tempIndices.data()), tBuffer, available * sizeof(T)); |
|
|
|
memcpy(mat->ptr(tempIndices.data()), tBuffer, available * sizeof(T)); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
int copyOffset = 0; |
|
|
|
char* buff = (char*)tBuffer; |
|
|
|
int copyCount = MIN((mat->size[mat->dims - 1] - tempIndices[mat->dims - 1]) * mat->channels(), available); |
|
|
|
size_t blockSize = mat->size[mat->dims-1] * mat->elemSize(); |
|
|
|
while (available > 0) { |
|
|
|
size_t firstPartialBlockSize = (mat->size[mat->dims-1] - tempIndices[mat->dims-1]) * mat->step[mat->dims-1]; |
|
|
|
memcpy(mat->ptr(tempIndices.data()), tBuffer + copyOffset, copyCount * sizeof(T)); |
|
|
|
for (int dim=mat->dims-2; dim>=0 && blockSize == mat->step[dim]; dim--) { |
|
|
|
if (updateIdx(mat, tempIndices, copyCount / mat->channels())) { |
|
|
|
blockSize *= mat->size[dim]; |
|
|
|
break; |
|
|
|
firstPartialBlockSize += (mat->size[dim] - (tempIndices[dim]+1)) * mat->step[dim]; |
|
|
|
} |
|
|
|
} |
|
|
|
available -= copyCount; |
|
|
|
size_t copyCount = (countBytes<firstPartialBlockSize)?countBytes:firstPartialBlockSize; |
|
|
|
copyOffset += copyCount * sizeof(T); |
|
|
|
uchar* data = mat->ptr(tempIndices.data()); |
|
|
|
copyCount = MIN(mat->size[mat->dims-1] * (int)mat->channels(), available); |
|
|
|
while(countBytes>0){ |
|
|
|
|
|
|
|
memcpy(data, buff, copyCount); |
|
|
|
|
|
|
|
updateIdx(mat, tempIndices, copyCount / mat->elemSize()); |
|
|
|
|
|
|
|
countBytes -= copyCount; |
|
|
|
|
|
|
|
buff += copyCount; |
|
|
|
|
|
|
|
copyCount = countBytes<blockSize?countBytes:blockSize; |
|
|
|
|
|
|
|
data = mat->ptr(tempIndices.data()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
return result; |
|
|
|