00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "PowerOfSqrtTwoZoomConstraint.h"
00017
00018 #include <iostream>
00019 #include <cmath>
00020
00021
00022 size_t
00023 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(size_t blockSize,
00024 RoundingDirection dir) const
00025 {
00026 int type, power;
00027 size_t rv = getNearestBlockSize(blockSize, type, power, dir);
00028 return rv;
00029 }
00030
00031 size_t
00032 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(size_t blockSize,
00033 int &type,
00034 int &power,
00035 RoundingDirection dir) const
00036 {
00037
00038
00039 size_t minCachePower = getMinCachePower();
00040
00041 if (blockSize < (1U << minCachePower)) {
00042 type = -1;
00043 power = 0;
00044 float val = 1.0, prevVal = 1.0;
00045 while (val + 0.01 < blockSize) {
00046 prevVal = val;
00047 val *= sqrt(2);
00048 }
00049 size_t rval;
00050 if (dir == RoundUp) rval = size_t(val + 0.01);
00051 else if (dir == RoundDown) rval = size_t(prevVal + 0.01);
00052 else if (val - blockSize < blockSize - prevVal) rval = size_t(val + 0.01);
00053 else rval = size_t(prevVal + 0.01);
00054
00055 return rval;
00056 }
00057
00058 unsigned int prevBase = (1 << minCachePower);
00059 unsigned int prevPower = minCachePower;
00060 unsigned int prevType = 0;
00061
00062 size_t result = 0;
00063
00064 for (unsigned int i = 0; ; ++i) {
00065
00066 power = minCachePower + i/2;
00067 type = i % 2;
00068
00069 unsigned int base;
00070 if (type == 0) {
00071 base = (1 << power);
00072 } else {
00073 base = (((unsigned int)((1 << minCachePower) * sqrt(2) + 0.01))
00074 << (power - minCachePower));
00075 }
00076
00077
00078
00079 if (base == blockSize) {
00080 result = base;
00081 break;
00082 }
00083
00084 if (base > blockSize) {
00085 if (dir == RoundNearest) {
00086 if (base - blockSize < blockSize - prevBase) {
00087 dir = RoundUp;
00088 } else {
00089 dir = RoundDown;
00090 }
00091 }
00092 if (dir == RoundUp) {
00093 result = base;
00094 break;
00095 } else {
00096 type = prevType;
00097 power = prevPower;
00098 result = prevBase;
00099 break;
00100 }
00101 }
00102
00103 prevType = type;
00104 prevPower = power;
00105 prevBase = base;
00106 }
00107
00108 if (result > getMaxZoomLevel()) result = getMaxZoomLevel();
00109 return result;
00110 }