Code-style consistency improvement:
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
This commit is contained in:
@@ -23,164 +23,146 @@
|
||||
const float DEG2RAD = 3.141593f / 180;
|
||||
const float EPSILON = 0.00001f;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transpose 2x2 matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix2& Matrix2::transpose()
|
||||
{
|
||||
std::swap(m[1], m[2]);
|
||||
return *this;
|
||||
std::swap(m[1], m[2]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// return the determinant of 2x2 matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
float Matrix2::getDeterminant()
|
||||
{
|
||||
return m[0] * m[3] - m[1] * m[2];
|
||||
return m[0] * m[3] - m[1] * m[2];
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// inverse of 2x2 matrix
|
||||
// If cannot find inverse, set identity matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix2& Matrix2::invert()
|
||||
{
|
||||
float determinant = getDeterminant();
|
||||
if(fabs(determinant) <= EPSILON)
|
||||
{
|
||||
return identity();
|
||||
}
|
||||
float determinant = getDeterminant();
|
||||
if (fabs(determinant) <= EPSILON)
|
||||
{
|
||||
return identity();
|
||||
}
|
||||
|
||||
float tmp = m[0]; // copy the first element
|
||||
float invDeterminant = 1.0f / determinant;
|
||||
m[0] = invDeterminant * m[3];
|
||||
m[1] = -invDeterminant * m[1];
|
||||
m[2] = -invDeterminant * m[2];
|
||||
m[3] = invDeterminant * tmp;
|
||||
float tmp = m[0]; // copy the first element
|
||||
float invDeterminant = 1.0f / determinant;
|
||||
m[0] = invDeterminant * m[3];
|
||||
m[1] = -invDeterminant * m[1];
|
||||
m[2] = -invDeterminant * m[2];
|
||||
m[3] = invDeterminant * tmp;
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transpose 3x3 matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix3& Matrix3::transpose()
|
||||
{
|
||||
std::swap(m[1], m[3]);
|
||||
std::swap(m[2], m[6]);
|
||||
std::swap(m[5], m[7]);
|
||||
std::swap(m[1], m[3]);
|
||||
std::swap(m[2], m[6]);
|
||||
std::swap(m[5], m[7]);
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// return determinant of 3x3 matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
float Matrix3::getDeterminant()
|
||||
{
|
||||
return m[0] * (m[4] * m[8] - m[5] * m[7]) -
|
||||
m[1] * (m[3] * m[8] - m[5] * m[6]) +
|
||||
m[2] * (m[3] * m[7] - m[4] * m[6]);
|
||||
return m[0] * (m[4] * m[8] - m[5] * m[7]) -
|
||||
m[1] * (m[3] * m[8] - m[5] * m[6]) +
|
||||
m[2] * (m[3] * m[7] - m[4] * m[6]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// inverse 3x3 matrix
|
||||
// If cannot find inverse, set identity matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix3& Matrix3::invert()
|
||||
{
|
||||
float determinant, invDeterminant;
|
||||
float tmp[9];
|
||||
float determinant, invDeterminant;
|
||||
float tmp[9];
|
||||
|
||||
tmp[0] = m[4] * m[8] - m[5] * m[7];
|
||||
tmp[1] = m[2] * m[7] - m[1] * m[8];
|
||||
tmp[2] = m[1] * m[5] - m[2] * m[4];
|
||||
tmp[3] = m[5] * m[6] - m[3] * m[8];
|
||||
tmp[4] = m[0] * m[8] - m[2] * m[6];
|
||||
tmp[5] = m[2] * m[3] - m[0] * m[5];
|
||||
tmp[6] = m[3] * m[7] - m[4] * m[6];
|
||||
tmp[7] = m[1] * m[6] - m[0] * m[7];
|
||||
tmp[8] = m[0] * m[4] - m[1] * m[3];
|
||||
tmp[0] = m[4] * m[8] - m[5] * m[7];
|
||||
tmp[1] = m[2] * m[7] - m[1] * m[8];
|
||||
tmp[2] = m[1] * m[5] - m[2] * m[4];
|
||||
tmp[3] = m[5] * m[6] - m[3] * m[8];
|
||||
tmp[4] = m[0] * m[8] - m[2] * m[6];
|
||||
tmp[5] = m[2] * m[3] - m[0] * m[5];
|
||||
tmp[6] = m[3] * m[7] - m[4] * m[6];
|
||||
tmp[7] = m[1] * m[6] - m[0] * m[7];
|
||||
tmp[8] = m[0] * m[4] - m[1] * m[3];
|
||||
|
||||
// check determinant if it is 0
|
||||
determinant = m[0] * tmp[0] + m[1] * tmp[3] + m[2] * tmp[6];
|
||||
if(fabs(determinant) <= EPSILON)
|
||||
{
|
||||
return identity(); // cannot inverse, make it idenety matrix
|
||||
}
|
||||
// check determinant if it is 0
|
||||
determinant = m[0] * tmp[0] + m[1] * tmp[3] + m[2] * tmp[6];
|
||||
if (fabs(determinant) <= EPSILON)
|
||||
{
|
||||
return identity(); // cannot inverse, make it idenety matrix
|
||||
}
|
||||
|
||||
// divide by the determinant
|
||||
invDeterminant = 1.0f / determinant;
|
||||
m[0] = invDeterminant * tmp[0];
|
||||
m[1] = invDeterminant * tmp[1];
|
||||
m[2] = invDeterminant * tmp[2];
|
||||
m[3] = invDeterminant * tmp[3];
|
||||
m[4] = invDeterminant * tmp[4];
|
||||
m[5] = invDeterminant * tmp[5];
|
||||
m[6] = invDeterminant * tmp[6];
|
||||
m[7] = invDeterminant * tmp[7];
|
||||
m[8] = invDeterminant * tmp[8];
|
||||
// divide by the determinant
|
||||
invDeterminant = 1.0f / determinant;
|
||||
m[0] = invDeterminant * tmp[0];
|
||||
m[1] = invDeterminant * tmp[1];
|
||||
m[2] = invDeterminant * tmp[2];
|
||||
m[3] = invDeterminant * tmp[3];
|
||||
m[4] = invDeterminant * tmp[4];
|
||||
m[5] = invDeterminant * tmp[5];
|
||||
m[6] = invDeterminant * tmp[6];
|
||||
m[7] = invDeterminant * tmp[7];
|
||||
m[8] = invDeterminant * tmp[8];
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transpose 4x4 matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::transpose()
|
||||
{
|
||||
std::swap(m[1], m[4]);
|
||||
std::swap(m[2], m[8]);
|
||||
std::swap(m[3], m[12]);
|
||||
std::swap(m[6], m[9]);
|
||||
std::swap(m[7], m[13]);
|
||||
std::swap(m[11], m[14]);
|
||||
std::swap(m[1], m[4]);
|
||||
std::swap(m[2], m[8]);
|
||||
std::swap(m[3], m[12]);
|
||||
std::swap(m[6], m[9]);
|
||||
std::swap(m[7], m[13]);
|
||||
std::swap(m[11], m[14]);
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// inverse 4x4 matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::invert()
|
||||
{
|
||||
// If the 4th row is [0,0,0,1] then it is affine matrix and
|
||||
// it has no projective transformation.
|
||||
if(m[3] == 0 && m[7] == 0 && m[11] == 0 && m[15] == 1)
|
||||
this->invertAffine();
|
||||
else
|
||||
{
|
||||
this->invertGeneral();
|
||||
/*@@ invertProjective() is not optimized (slower than generic one)
|
||||
// If the 4th row is [0,0,0,1] then it is affine matrix and
|
||||
// it has no projective transformation.
|
||||
if (m[3] == 0 && m[7] == 0 && m[11] == 0 && m[15] == 1)
|
||||
this->invertAffine();
|
||||
else
|
||||
{
|
||||
this->invertGeneral();
|
||||
/*@@ invertProjective() is not optimized (slower than generic one)
|
||||
if(fabs(m[0]*m[5] - m[1]*m[4]) > EPSILON)
|
||||
this->invertProjective(); // inverse using matrix partition
|
||||
else
|
||||
this->invertGeneral(); // generalized inverse
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compute the inverse of 4x4 Euclidean transformation matrix
|
||||
//
|
||||
@@ -204,33 +186,37 @@ Matrix4& Matrix4::invert()
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::invertEuclidean()
|
||||
{
|
||||
// transpose 3x3 rotation matrix part
|
||||
// | R^T | 0 |
|
||||
// | ----+-- |
|
||||
// | 0 | 1 |
|
||||
float tmp;
|
||||
tmp = m[1]; m[1] = m[4]; m[4] = tmp;
|
||||
tmp = m[2]; m[2] = m[8]; m[8] = tmp;
|
||||
tmp = m[6]; m[6] = m[9]; m[9] = tmp;
|
||||
// transpose 3x3 rotation matrix part
|
||||
// | R^T | 0 |
|
||||
// | ----+-- |
|
||||
// | 0 | 1 |
|
||||
float tmp;
|
||||
tmp = m[1];
|
||||
m[1] = m[4];
|
||||
m[4] = tmp;
|
||||
tmp = m[2];
|
||||
m[2] = m[8];
|
||||
m[8] = tmp;
|
||||
tmp = m[6];
|
||||
m[6] = m[9];
|
||||
m[9] = tmp;
|
||||
|
||||
// compute translation part -R^T * T
|
||||
// | 0 | -R^T x |
|
||||
// | --+------- |
|
||||
// | 0 | 0 |
|
||||
float x = m[12];
|
||||
float y = m[13];
|
||||
float z = m[14];
|
||||
m[12] = -(m[0] * x + m[4] * y + m[8] * z);
|
||||
m[13] = -(m[1] * x + m[5] * y + m[9] * z);
|
||||
m[14] = -(m[2] * x + m[6] * y + m[10]* z);
|
||||
// compute translation part -R^T * T
|
||||
// | 0 | -R^T x |
|
||||
// | --+------- |
|
||||
// | 0 | 0 |
|
||||
float x = m[12];
|
||||
float y = m[13];
|
||||
float z = m[14];
|
||||
m[12] = -(m[0] * x + m[4] * y + m[8] * z);
|
||||
m[13] = -(m[1] * x + m[5] * y + m[9] * z);
|
||||
m[14] = -(m[2] * x + m[6] * y + m[10] * z);
|
||||
|
||||
// last row should be unchanged (0,0,0,1)
|
||||
// last row should be unchanged (0,0,0,1)
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compute the inverse of a 4x4 affine transformation matrix
|
||||
//
|
||||
@@ -249,30 +235,34 @@ Matrix4& Matrix4::invertEuclidean()
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::invertAffine()
|
||||
{
|
||||
// R^-1
|
||||
Matrix3 r(m[0],m[1],m[2], m[4],m[5],m[6], m[8],m[9],m[10]);
|
||||
r.invert();
|
||||
m[0] = r[0]; m[1] = r[1]; m[2] = r[2];
|
||||
m[4] = r[3]; m[5] = r[4]; m[6] = r[5];
|
||||
m[8] = r[6]; m[9] = r[7]; m[10]= r[8];
|
||||
// R^-1
|
||||
Matrix3 r(m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]);
|
||||
r.invert();
|
||||
m[0] = r[0];
|
||||
m[1] = r[1];
|
||||
m[2] = r[2];
|
||||
m[4] = r[3];
|
||||
m[5] = r[4];
|
||||
m[6] = r[5];
|
||||
m[8] = r[6];
|
||||
m[9] = r[7];
|
||||
m[10] = r[8];
|
||||
|
||||
// -R^-1 * T
|
||||
float x = m[12];
|
||||
float y = m[13];
|
||||
float z = m[14];
|
||||
m[12] = -(r[0] * x + r[3] * y + r[6] * z);
|
||||
m[13] = -(r[1] * x + r[4] * y + r[7] * z);
|
||||
m[14] = -(r[2] * x + r[5] * y + r[8] * z);
|
||||
// -R^-1 * T
|
||||
float x = m[12];
|
||||
float y = m[13];
|
||||
float z = m[14];
|
||||
m[12] = -(r[0] * x + r[3] * y + r[6] * z);
|
||||
m[13] = -(r[1] * x + r[4] * y + r[7] * z);
|
||||
m[14] = -(r[2] * x + r[5] * y + r[8] * z);
|
||||
|
||||
// last row should be unchanged (0,0,0,1)
|
||||
//m[3] = m[7] = m[11] = 0.0f;
|
||||
//m[15] = 1.0f;
|
||||
// last row should be unchanged (0,0,0,1)
|
||||
//m[3] = m[7] = m[11] = 0.0f;
|
||||
//m[15] = 1.0f;
|
||||
|
||||
return * this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// inverse matrix using matrix partitioning (blockwise inverse)
|
||||
// It devides a 4x4 matrix into 4 of 2x2 matrices. It works in case of where
|
||||
@@ -293,54 +283,64 @@ Matrix4& Matrix4::invertAffine()
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::invertProjective()
|
||||
{
|
||||
// partition
|
||||
Matrix2 a(m[0], m[1], m[4], m[5]);
|
||||
Matrix2 b(m[8], m[9], m[12], m[13]);
|
||||
Matrix2 c(m[2], m[3], m[6], m[7]);
|
||||
Matrix2 d(m[10], m[11], m[14], m[15]);
|
||||
// partition
|
||||
Matrix2 a(m[0], m[1], m[4], m[5]);
|
||||
Matrix2 b(m[8], m[9], m[12], m[13]);
|
||||
Matrix2 c(m[2], m[3], m[6], m[7]);
|
||||
Matrix2 d(m[10], m[11], m[14], m[15]);
|
||||
|
||||
// pre-compute repeated parts
|
||||
a.invert(); // A^-1
|
||||
Matrix2 ab = a * b; // A^-1 * B
|
||||
Matrix2 ca = c * a; // C * A^-1
|
||||
Matrix2 cab = ca * b; // C * A^-1 * B
|
||||
Matrix2 dcab = d - cab; // D - C * A^-1 * B
|
||||
// pre-compute repeated parts
|
||||
a.invert(); // A^-1
|
||||
Matrix2 ab = a * b; // A^-1 * B
|
||||
Matrix2 ca = c * a; // C * A^-1
|
||||
Matrix2 cab = ca * b; // C * A^-1 * B
|
||||
Matrix2 dcab = d - cab; // D - C * A^-1 * B
|
||||
|
||||
// check determinant if |D - C * A^-1 * B| = 0
|
||||
//NOTE: this function assumes det(A) is already checked. if |A|=0 then,
|
||||
// cannot use this function.
|
||||
float determinant = dcab[0] * dcab[3] - dcab[1] * dcab[2];
|
||||
if(fabs(determinant) <= EPSILON)
|
||||
{
|
||||
return identity();
|
||||
}
|
||||
// check determinant if |D - C * A^-1 * B| = 0
|
||||
//NOTE: this function assumes det(A) is already checked. if |A|=0 then,
|
||||
// cannot use this function.
|
||||
float determinant = dcab[0] * dcab[3] - dcab[1] * dcab[2];
|
||||
if (fabs(determinant) <= EPSILON)
|
||||
{
|
||||
return identity();
|
||||
}
|
||||
|
||||
// compute D' and -D'
|
||||
Matrix2 d1 = dcab; // (D - C * A^-1 * B)
|
||||
d1.invert(); // (D - C * A^-1 * B)^-1
|
||||
Matrix2 d2 = -d1; // -(D - C * A^-1 * B)^-1
|
||||
// compute D' and -D'
|
||||
Matrix2 d1 = dcab; // (D - C * A^-1 * B)
|
||||
d1.invert(); // (D - C * A^-1 * B)^-1
|
||||
Matrix2 d2 = -d1; // -(D - C * A^-1 * B)^-1
|
||||
|
||||
// compute C'
|
||||
Matrix2 c1 = d2 * ca; // -D' * (C * A^-1)
|
||||
// compute C'
|
||||
Matrix2 c1 = d2 * ca; // -D' * (C * A^-1)
|
||||
|
||||
// compute B'
|
||||
Matrix2 b1 = ab * d2; // (A^-1 * B) * -D'
|
||||
// compute B'
|
||||
Matrix2 b1 = ab * d2; // (A^-1 * B) * -D'
|
||||
|
||||
// compute A'
|
||||
Matrix2 a1 = a - (ab * c1); // A^-1 - (A^-1 * B) * C'
|
||||
// compute A'
|
||||
Matrix2 a1 = a - (ab * c1); // A^-1 - (A^-1 * B) * C'
|
||||
|
||||
// assemble inverse matrix
|
||||
m[0] = a1[0]; m[4] = a1[2]; /*|*/ m[8] = b1[0]; m[12]= b1[2];
|
||||
m[1] = a1[1]; m[5] = a1[3]; /*|*/ m[9] = b1[1]; m[13]= b1[3];
|
||||
/*-----------------------------+-----------------------------*/
|
||||
m[2] = c1[0]; m[6] = c1[2]; /*|*/ m[10]= d1[0]; m[14]= d1[2];
|
||||
m[3] = c1[1]; m[7] = c1[3]; /*|*/ m[11]= d1[1]; m[15]= d1[3];
|
||||
// assemble inverse matrix
|
||||
m[0] = a1[0];
|
||||
m[4] = a1[2]; /*|*/
|
||||
m[8] = b1[0];
|
||||
m[12] = b1[2];
|
||||
m[1] = a1[1];
|
||||
m[5] = a1[3]; /*|*/
|
||||
m[9] = b1[1];
|
||||
m[13] = b1[3];
|
||||
/*-----------------------------+-----------------------------*/
|
||||
m[2] = c1[0];
|
||||
m[6] = c1[2]; /*|*/
|
||||
m[10] = d1[0];
|
||||
m[14] = d1[2];
|
||||
m[3] = c1[1];
|
||||
m[7] = c1[3]; /*|*/
|
||||
m[11] = d1[1];
|
||||
m[15] = d1[3];
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compute the inverse of a general 4x4 matrix using Cramer's Rule
|
||||
// If cannot find inverse, return indentity matrix
|
||||
@@ -348,234 +348,242 @@ Matrix4& Matrix4::invertProjective()
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::invertGeneral()
|
||||
{
|
||||
// get cofactors of minor matrices
|
||||
float cofactor0 = getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]);
|
||||
float cofactor1 = getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]);
|
||||
float cofactor2 = getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]);
|
||||
float cofactor3 = getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]);
|
||||
// get cofactors of minor matrices
|
||||
float cofactor0 = getCofactor(m[5], m[6], m[7], m[9], m[10], m[11], m[13], m[14], m[15]);
|
||||
float cofactor1 = getCofactor(m[4], m[6], m[7], m[8], m[10], m[11], m[12], m[14], m[15]);
|
||||
float cofactor2 = getCofactor(m[4], m[5], m[7], m[8], m[9], m[11], m[12], m[13], m[15]);
|
||||
float cofactor3 = getCofactor(m[4], m[5], m[6], m[8], m[9], m[10], m[12], m[13], m[14]);
|
||||
|
||||
// get determinant
|
||||
float determinant = m[0] * cofactor0 - m[1] * cofactor1 + m[2] * cofactor2 - m[3] * cofactor3;
|
||||
if(fabs(determinant) <= EPSILON)
|
||||
{
|
||||
return identity();
|
||||
}
|
||||
// get determinant
|
||||
float determinant = m[0] * cofactor0 - m[1] * cofactor1 + m[2] * cofactor2 - m[3] * cofactor3;
|
||||
if (fabs(determinant) <= EPSILON)
|
||||
{
|
||||
return identity();
|
||||
}
|
||||
|
||||
// get rest of cofactors for adj(M)
|
||||
float cofactor4 = getCofactor(m[1],m[2],m[3], m[9],m[10],m[11], m[13],m[14],m[15]);
|
||||
float cofactor5 = getCofactor(m[0],m[2],m[3], m[8],m[10],m[11], m[12],m[14],m[15]);
|
||||
float cofactor6 = getCofactor(m[0],m[1],m[3], m[8],m[9], m[11], m[12],m[13],m[15]);
|
||||
float cofactor7 = getCofactor(m[0],m[1],m[2], m[8],m[9], m[10], m[12],m[13],m[14]);
|
||||
// get rest of cofactors for adj(M)
|
||||
float cofactor4 = getCofactor(m[1], m[2], m[3], m[9], m[10], m[11], m[13], m[14], m[15]);
|
||||
float cofactor5 = getCofactor(m[0], m[2], m[3], m[8], m[10], m[11], m[12], m[14], m[15]);
|
||||
float cofactor6 = getCofactor(m[0], m[1], m[3], m[8], m[9], m[11], m[12], m[13], m[15]);
|
||||
float cofactor7 = getCofactor(m[0], m[1], m[2], m[8], m[9], m[10], m[12], m[13], m[14]);
|
||||
|
||||
float cofactor8 = getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[13],m[14],m[15]);
|
||||
float cofactor9 = getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[12],m[14],m[15]);
|
||||
float cofactor10= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[12],m[13],m[15]);
|
||||
float cofactor11= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[12],m[13],m[14]);
|
||||
float cofactor8 = getCofactor(m[1], m[2], m[3], m[5], m[6], m[7], m[13], m[14], m[15]);
|
||||
float cofactor9 = getCofactor(m[0], m[2], m[3], m[4], m[6], m[7], m[12], m[14], m[15]);
|
||||
float cofactor10 = getCofactor(m[0], m[1], m[3], m[4], m[5], m[7], m[12], m[13], m[15]);
|
||||
float cofactor11 = getCofactor(m[0], m[1], m[2], m[4], m[5], m[6], m[12], m[13], m[14]);
|
||||
|
||||
float cofactor12= getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[9], m[10],m[11]);
|
||||
float cofactor13= getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[8], m[10],m[11]);
|
||||
float cofactor14= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[8], m[9], m[11]);
|
||||
float cofactor15= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[8], m[9], m[10]);
|
||||
float cofactor12 = getCofactor(m[1], m[2], m[3], m[5], m[6], m[7], m[9], m[10], m[11]);
|
||||
float cofactor13 = getCofactor(m[0], m[2], m[3], m[4], m[6], m[7], m[8], m[10], m[11]);
|
||||
float cofactor14 = getCofactor(m[0], m[1], m[3], m[4], m[5], m[7], m[8], m[9], m[11]);
|
||||
float cofactor15 = getCofactor(m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]);
|
||||
|
||||
// build inverse matrix = adj(M) / det(M)
|
||||
// adjugate of M is the transpose of the cofactor matrix of M
|
||||
float invDeterminant = 1.0f / determinant;
|
||||
m[0] = invDeterminant * cofactor0;
|
||||
m[1] = -invDeterminant * cofactor4;
|
||||
m[2] = invDeterminant * cofactor8;
|
||||
m[3] = -invDeterminant * cofactor12;
|
||||
// build inverse matrix = adj(M) / det(M)
|
||||
// adjugate of M is the transpose of the cofactor matrix of M
|
||||
float invDeterminant = 1.0f / determinant;
|
||||
m[0] = invDeterminant * cofactor0;
|
||||
m[1] = -invDeterminant * cofactor4;
|
||||
m[2] = invDeterminant * cofactor8;
|
||||
m[3] = -invDeterminant * cofactor12;
|
||||
|
||||
m[4] = -invDeterminant * cofactor1;
|
||||
m[5] = invDeterminant * cofactor5;
|
||||
m[6] = -invDeterminant * cofactor9;
|
||||
m[7] = invDeterminant * cofactor13;
|
||||
m[4] = -invDeterminant * cofactor1;
|
||||
m[5] = invDeterminant * cofactor5;
|
||||
m[6] = -invDeterminant * cofactor9;
|
||||
m[7] = invDeterminant * cofactor13;
|
||||
|
||||
m[8] = invDeterminant * cofactor2;
|
||||
m[9] = -invDeterminant * cofactor6;
|
||||
m[10]= invDeterminant * cofactor10;
|
||||
m[11]= -invDeterminant * cofactor14;
|
||||
m[8] = invDeterminant * cofactor2;
|
||||
m[9] = -invDeterminant * cofactor6;
|
||||
m[10] = invDeterminant * cofactor10;
|
||||
m[11] = -invDeterminant * cofactor14;
|
||||
|
||||
m[12]= -invDeterminant * cofactor3;
|
||||
m[13]= invDeterminant * cofactor7;
|
||||
m[14]= -invDeterminant * cofactor11;
|
||||
m[15]= invDeterminant * cofactor15;
|
||||
m[12] = -invDeterminant * cofactor3;
|
||||
m[13] = invDeterminant * cofactor7;
|
||||
m[14] = -invDeterminant * cofactor11;
|
||||
m[15] = invDeterminant * cofactor15;
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// return determinant of 4x4 matrix
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
float Matrix4::getDeterminant()
|
||||
{
|
||||
return m[0] * getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]) -
|
||||
m[1] * getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]) +
|
||||
m[2] * getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]) -
|
||||
m[3] * getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]);
|
||||
return m[0] * getCofactor(m[5], m[6], m[7], m[9], m[10], m[11], m[13], m[14], m[15]) -
|
||||
m[1] * getCofactor(m[4], m[6], m[7], m[8], m[10], m[11], m[12], m[14], m[15]) +
|
||||
m[2] * getCofactor(m[4], m[5], m[7], m[8], m[9], m[11], m[12], m[13], m[15]) -
|
||||
m[3] * getCofactor(m[4], m[5], m[6], m[8], m[9], m[10], m[12], m[13], m[14]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compute cofactor of 3x3 minor matrix without sign
|
||||
// input params are 9 elements of the minor matrix
|
||||
// NOTE: The caller must know its sign.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
float Matrix4::getCofactor(float m0, float m1, float m2,
|
||||
float m3, float m4, float m5,
|
||||
float m6, float m7, float m8)
|
||||
float m3, float m4, float m5,
|
||||
float m6, float m7, float m8)
|
||||
{
|
||||
return m0 * (m4 * m8 - m5 * m7) -
|
||||
m1 * (m3 * m8 - m5 * m6) +
|
||||
m2 * (m3 * m7 - m4 * m6);
|
||||
return m0 * (m4 * m8 - m5 * m7) -
|
||||
m1 * (m3 * m8 - m5 * m6) +
|
||||
m2 * (m3 * m7 - m4 * m6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// translate this matrix by (x, y, z)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::translate(const Vector3& v)
|
||||
{
|
||||
return translate(v.x, v.y, v.z);
|
||||
return translate(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
Matrix4& Matrix4::translate(float x, float y, float z)
|
||||
{
|
||||
m[0] += m[3] * x; m[4] += m[7] * x; m[8] += m[11]* x; m[12]+= m[15]* x;
|
||||
m[1] += m[3] * y; m[5] += m[7] * y; m[9] += m[11]* y; m[13]+= m[15]* y;
|
||||
m[2] += m[3] * z; m[6] += m[7] * z; m[10]+= m[11]* z; m[14]+= m[15]* z;
|
||||
m[0] += m[3] * x;
|
||||
m[4] += m[7] * x;
|
||||
m[8] += m[11] * x;
|
||||
m[12] += m[15] * x;
|
||||
m[1] += m[3] * y;
|
||||
m[5] += m[7] * y;
|
||||
m[9] += m[11] * y;
|
||||
m[13] += m[15] * y;
|
||||
m[2] += m[3] * z;
|
||||
m[6] += m[7] * z;
|
||||
m[10] += m[11] * z;
|
||||
m[14] += m[15] * z;
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// uniform scale
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::scale(float s)
|
||||
{
|
||||
return scale(s, s, s);
|
||||
return scale(s, s, s);
|
||||
}
|
||||
|
||||
Matrix4& Matrix4::scale(float x, float y, float z)
|
||||
{
|
||||
m[0] *= x; m[4] *= x; m[8] *= x; m[12] *= x;
|
||||
m[1] *= y; m[5] *= y; m[9] *= y; m[13] *= y;
|
||||
m[2] *= z; m[6] *= z; m[10]*= z; m[14] *= z;
|
||||
return *this;
|
||||
m[0] *= x;
|
||||
m[4] *= x;
|
||||
m[8] *= x;
|
||||
m[12] *= x;
|
||||
m[1] *= y;
|
||||
m[5] *= y;
|
||||
m[9] *= y;
|
||||
m[13] *= y;
|
||||
m[2] *= z;
|
||||
m[6] *= z;
|
||||
m[10] *= z;
|
||||
m[14] *= z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// build a rotation matrix with given angle(degree) and rotation axis, then
|
||||
// multiply it with this object
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Matrix4& Matrix4::rotate(float angle, const Vector3& axis)
|
||||
{
|
||||
return rotate(angle, axis.x, axis.y, axis.z);
|
||||
return rotate(angle, axis.x, axis.y, axis.z);
|
||||
}
|
||||
|
||||
Matrix4& Matrix4::rotate(float angle, float x, float y, float z)
|
||||
{
|
||||
float c = cosf(angle * DEG2RAD); // cosine
|
||||
float s = sinf(angle * DEG2RAD); // sine
|
||||
float c1 = 1.0f - c; // 1 - c
|
||||
float m0 = m[0], m4 = m[4], m8 = m[8], m12= m[12],
|
||||
m1 = m[1], m5 = m[5], m9 = m[9], m13= m[13],
|
||||
m2 = m[2], m6 = m[6], m10= m[10], m14= m[14];
|
||||
float c = cosf(angle * DEG2RAD); // cosine
|
||||
float s = sinf(angle * DEG2RAD); // sine
|
||||
float c1 = 1.0f - c; // 1 - c
|
||||
float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12],
|
||||
m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13],
|
||||
m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14];
|
||||
|
||||
// build rotation matrix
|
||||
float r0 = x * x * c1 + c;
|
||||
float r1 = x * y * c1 + z * s;
|
||||
float r2 = x * z * c1 - y * s;
|
||||
float r4 = x * y * c1 - z * s;
|
||||
float r5 = y * y * c1 + c;
|
||||
float r6 = y * z * c1 + x * s;
|
||||
float r8 = x * z * c1 + y * s;
|
||||
float r9 = y * z * c1 - x * s;
|
||||
float r10= z * z * c1 + c;
|
||||
// build rotation matrix
|
||||
float r0 = x * x * c1 + c;
|
||||
float r1 = x * y * c1 + z * s;
|
||||
float r2 = x * z * c1 - y * s;
|
||||
float r4 = x * y * c1 - z * s;
|
||||
float r5 = y * y * c1 + c;
|
||||
float r6 = y * z * c1 + x * s;
|
||||
float r8 = x * z * c1 + y * s;
|
||||
float r9 = y * z * c1 - x * s;
|
||||
float r10 = z * z * c1 + c;
|
||||
|
||||
// multiply rotation matrix
|
||||
m[0] = r0 * m0 + r4 * m1 + r8 * m2;
|
||||
m[1] = r1 * m0 + r5 * m1 + r9 * m2;
|
||||
m[2] = r2 * m0 + r6 * m1 + r10* m2;
|
||||
m[4] = r0 * m4 + r4 * m5 + r8 * m6;
|
||||
m[5] = r1 * m4 + r5 * m5 + r9 * m6;
|
||||
m[6] = r2 * m4 + r6 * m5 + r10* m6;
|
||||
m[8] = r0 * m8 + r4 * m9 + r8 * m10;
|
||||
m[9] = r1 * m8 + r5 * m9 + r9 * m10;
|
||||
m[10]= r2 * m8 + r6 * m9 + r10* m10;
|
||||
m[12]= r0 * m12+ r4 * m13+ r8 * m14;
|
||||
m[13]= r1 * m12+ r5 * m13+ r9 * m14;
|
||||
m[14]= r2 * m12+ r6 * m13+ r10* m14;
|
||||
// multiply rotation matrix
|
||||
m[0] = r0 * m0 + r4 * m1 + r8 * m2;
|
||||
m[1] = r1 * m0 + r5 * m1 + r9 * m2;
|
||||
m[2] = r2 * m0 + r6 * m1 + r10 * m2;
|
||||
m[4] = r0 * m4 + r4 * m5 + r8 * m6;
|
||||
m[5] = r1 * m4 + r5 * m5 + r9 * m6;
|
||||
m[6] = r2 * m4 + r6 * m5 + r10 * m6;
|
||||
m[8] = r0 * m8 + r4 * m9 + r8 * m10;
|
||||
m[9] = r1 * m8 + r5 * m9 + r9 * m10;
|
||||
m[10] = r2 * m8 + r6 * m9 + r10 * m10;
|
||||
m[12] = r0 * m12 + r4 * m13 + r8 * m14;
|
||||
m[13] = r1 * m12 + r5 * m13 + r9 * m14;
|
||||
m[14] = r2 * m12 + r6 * m13 + r10 * m14;
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix4& Matrix4::rotateX(float angle)
|
||||
{
|
||||
float c = cosf(angle * DEG2RAD);
|
||||
float s = sinf(angle * DEG2RAD);
|
||||
float m1 = m[1], m2 = m[2],
|
||||
m5 = m[5], m6 = m[6],
|
||||
m9 = m[9], m10= m[10],
|
||||
m13= m[13], m14= m[14];
|
||||
float c = cosf(angle * DEG2RAD);
|
||||
float s = sinf(angle * DEG2RAD);
|
||||
float m1 = m[1], m2 = m[2],
|
||||
m5 = m[5], m6 = m[6],
|
||||
m9 = m[9], m10 = m[10],
|
||||
m13 = m[13], m14 = m[14];
|
||||
|
||||
m[1] = m1 * c + m2 *-s;
|
||||
m[2] = m1 * s + m2 * c;
|
||||
m[5] = m5 * c + m6 *-s;
|
||||
m[6] = m5 * s + m6 * c;
|
||||
m[9] = m9 * c + m10*-s;
|
||||
m[10]= m9 * s + m10* c;
|
||||
m[13]= m13* c + m14*-s;
|
||||
m[14]= m13* s + m14* c;
|
||||
m[1] = m1 * c + m2 * -s;
|
||||
m[2] = m1 * s + m2 * c;
|
||||
m[5] = m5 * c + m6 * -s;
|
||||
m[6] = m5 * s + m6 * c;
|
||||
m[9] = m9 * c + m10 * -s;
|
||||
m[10] = m9 * s + m10 * c;
|
||||
m[13] = m13 * c + m14 * -s;
|
||||
m[14] = m13 * s + m14 * c;
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix4& Matrix4::rotateY(float angle)
|
||||
{
|
||||
float c = cosf(angle * DEG2RAD);
|
||||
float s = sinf(angle * DEG2RAD);
|
||||
float m0 = m[0], m2 = m[2],
|
||||
m4 = m[4], m6 = m[6],
|
||||
m8 = m[8], m10= m[10],
|
||||
m12= m[12], m14= m[14];
|
||||
float c = cosf(angle * DEG2RAD);
|
||||
float s = sinf(angle * DEG2RAD);
|
||||
float m0 = m[0], m2 = m[2],
|
||||
m4 = m[4], m6 = m[6],
|
||||
m8 = m[8], m10 = m[10],
|
||||
m12 = m[12], m14 = m[14];
|
||||
|
||||
m[0] = m0 * c + m2 * s;
|
||||
m[2] = m0 *-s + m2 * c;
|
||||
m[4] = m4 * c + m6 * s;
|
||||
m[6] = m4 *-s + m6 * c;
|
||||
m[8] = m8 * c + m10* s;
|
||||
m[10]= m8 *-s + m10* c;
|
||||
m[12]= m12* c + m14* s;
|
||||
m[14]= m12*-s + m14* c;
|
||||
m[0] = m0 * c + m2 * s;
|
||||
m[2] = m0 * -s + m2 * c;
|
||||
m[4] = m4 * c + m6 * s;
|
||||
m[6] = m4 * -s + m6 * c;
|
||||
m[8] = m8 * c + m10 * s;
|
||||
m[10] = m8 * -s + m10 * c;
|
||||
m[12] = m12 * c + m14 * s;
|
||||
m[14] = m12 * -s + m14 * c;
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix4& Matrix4::rotateZ(float angle)
|
||||
{
|
||||
float c = cosf(angle * DEG2RAD);
|
||||
float s = sinf(angle * DEG2RAD);
|
||||
float m0 = m[0], m1 = m[1],
|
||||
m4 = m[4], m5 = m[5],
|
||||
m8 = m[8], m9 = m[9],
|
||||
m12= m[12], m13= m[13];
|
||||
float c = cosf(angle * DEG2RAD);
|
||||
float s = sinf(angle * DEG2RAD);
|
||||
float m0 = m[0], m1 = m[1],
|
||||
m4 = m[4], m5 = m[5],
|
||||
m8 = m[8], m9 = m[9],
|
||||
m12 = m[12], m13 = m[13];
|
||||
|
||||
m[0] = m0 * c + m1 *-s;
|
||||
m[1] = m0 * s + m1 * c;
|
||||
m[4] = m4 * c + m5 *-s;
|
||||
m[5] = m4 * s + m5 * c;
|
||||
m[8] = m8 * c + m9 *-s;
|
||||
m[9] = m8 * s + m9 * c;
|
||||
m[12]= m12* c + m13*-s;
|
||||
m[13]= m12* s + m13* c;
|
||||
m[0] = m0 * c + m1 * -s;
|
||||
m[1] = m0 * s + m1 * c;
|
||||
m[4] = m4 * c + m5 * -s;
|
||||
m[5] = m4 * s + m5 * c;
|
||||
m[8] = m8 * c + m9 * -s;
|
||||
m[9] = m8 * s + m9 * c;
|
||||
m[12] = m12 * c + m13 * -s;
|
||||
m[13] = m12 * s + m13 * c;
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,6 @@
|
||||
// Copyright (C) 2007-2013 Song Ho Ahn
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef VECTORS_H_DEF
|
||||
#define VECTORS_H_DEF
|
||||
|
||||
@@ -22,508 +21,619 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct Vector2
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float x;
|
||||
float y;
|
||||
|
||||
// ctors
|
||||
Vector2() : x(0), y(0) {};
|
||||
Vector2(float x, float y) : x(x), y(y) {};
|
||||
// ctors
|
||||
Vector2() : x(0), y(0){};
|
||||
Vector2(float x, float y) : x(x), y(y){};
|
||||
|
||||
// utils functions
|
||||
void set(float x, float y);
|
||||
float length() const; //
|
||||
float distance(const Vector2& vec) const; // distance between two vectors
|
||||
Vector2& normalize(); //
|
||||
float dot(const Vector2& vec) const; // dot product
|
||||
bool equal(const Vector2& vec, float e) const; // compare with epsilon
|
||||
// utils functions
|
||||
void set(float x, float y);
|
||||
float length() const; //
|
||||
float distance(const Vector2& vec) const; // distance between two vectors
|
||||
Vector2& normalize(); //
|
||||
float dot(const Vector2& vec) const; // dot product
|
||||
bool equal(const Vector2& vec, float e) const; // compare with epsilon
|
||||
|
||||
// operators
|
||||
Vector2 operator-() const; // unary operator (negate)
|
||||
Vector2 operator+(const Vector2& rhs) const; // add rhs
|
||||
Vector2 operator-(const Vector2& rhs) const; // subtract rhs
|
||||
Vector2& operator+=(const Vector2& rhs); // add rhs and update this object
|
||||
Vector2& operator-=(const Vector2& rhs); // subtract rhs and update this object
|
||||
Vector2 operator*(const float scale) const; // scale
|
||||
Vector2 operator*(const Vector2& rhs) const; // multiply each element
|
||||
Vector2& operator*=(const float scale); // scale and update this object
|
||||
Vector2& operator*=(const Vector2& rhs); // multiply each element and update this object
|
||||
Vector2 operator/(const float scale) const; // inverse scale
|
||||
Vector2& operator/=(const float scale); // scale and update this object
|
||||
bool operator==(const Vector2& rhs) const; // exact compare, no epsilon
|
||||
bool operator!=(const Vector2& rhs) const; // exact compare, no epsilon
|
||||
bool operator<(const Vector2& rhs) const; // comparison for sort
|
||||
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||
float& operator[](int index); // subscript operator v[0], v[1]
|
||||
// operators
|
||||
Vector2 operator-() const; // unary operator (negate)
|
||||
Vector2 operator+(const Vector2& rhs) const; // add rhs
|
||||
Vector2 operator-(const Vector2& rhs) const; // subtract rhs
|
||||
Vector2& operator+=(const Vector2& rhs); // add rhs and update this object
|
||||
Vector2& operator-=(const Vector2& rhs); // subtract rhs and update this object
|
||||
Vector2 operator*(const float scale) const; // scale
|
||||
Vector2 operator*(const Vector2& rhs) const; // multiply each element
|
||||
Vector2& operator*=(const float scale); // scale and update this object
|
||||
Vector2& operator*=(const Vector2& rhs); // multiply each element and update this object
|
||||
Vector2 operator/(const float scale) const; // inverse scale
|
||||
Vector2& operator/=(const float scale); // scale and update this object
|
||||
bool operator==(const Vector2& rhs) const; // exact compare, no epsilon
|
||||
bool operator!=(const Vector2& rhs) const; // exact compare, no epsilon
|
||||
bool operator<(const Vector2& rhs) const; // comparison for sort
|
||||
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||
float& operator[](int index); // subscript operator v[0], v[1]
|
||||
|
||||
friend Vector2 operator*(const float a, const Vector2 vec);
|
||||
friend std::ostream& operator<<(std::ostream& os, const Vector2& vec);
|
||||
friend Vector2 operator*(const float a, const Vector2 vec);
|
||||
friend std::ostream& operator<<(std::ostream& os, const Vector2& vec);
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 3D vector
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct Vector3
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
|
||||
// ctors
|
||||
Vector3() : x(0), y(0), z(0) {};
|
||||
Vector3(float x, float y, float z) : x(x), y(y), z(z) {};
|
||||
// ctors
|
||||
Vector3() : x(0), y(0), z(0){};
|
||||
Vector3(float x, float y, float z) : x(x), y(y), z(z){};
|
||||
|
||||
// utils functions
|
||||
void set(float x, float y, float z);
|
||||
float length() const; //
|
||||
float distance(const Vector3& vec) const; // distance between two vectors
|
||||
Vector3& normalize(); //
|
||||
float dot(const Vector3& vec) const; // dot product
|
||||
Vector3 cross(const Vector3& vec) const; // cross product
|
||||
bool equal(const Vector3& vec, float e) const; // compare with epsilon
|
||||
// utils functions
|
||||
void set(float x, float y, float z);
|
||||
float length() const; //
|
||||
float distance(const Vector3& vec) const; // distance between two vectors
|
||||
Vector3& normalize(); //
|
||||
float dot(const Vector3& vec) const; // dot product
|
||||
Vector3 cross(const Vector3& vec) const; // cross product
|
||||
bool equal(const Vector3& vec, float e) const; // compare with epsilon
|
||||
|
||||
// operators
|
||||
Vector3 operator-() const; // unary operator (negate)
|
||||
Vector3 operator+(const Vector3& rhs) const; // add rhs
|
||||
Vector3 operator-(const Vector3& rhs) const; // subtract rhs
|
||||
Vector3& operator+=(const Vector3& rhs); // add rhs and update this object
|
||||
Vector3& operator-=(const Vector3& rhs); // subtract rhs and update this object
|
||||
Vector3 operator*(const float scale) const; // scale
|
||||
Vector3 operator*(const Vector3& rhs) const; // multiplay each element
|
||||
Vector3& operator*=(const float scale); // scale and update this object
|
||||
Vector3& operator*=(const Vector3& rhs); // product each element and update this object
|
||||
Vector3 operator/(const float scale) const; // inverse scale
|
||||
Vector3& operator/=(const float scale); // scale and update this object
|
||||
bool operator==(const Vector3& rhs) const; // exact compare, no epsilon
|
||||
bool operator!=(const Vector3& rhs) const; // exact compare, no epsilon
|
||||
bool operator<(const Vector3& rhs) const; // comparison for sort
|
||||
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||
float& operator[](int index); // subscript operator v[0], v[1]
|
||||
// operators
|
||||
Vector3 operator-() const; // unary operator (negate)
|
||||
Vector3 operator+(const Vector3& rhs) const; // add rhs
|
||||
Vector3 operator-(const Vector3& rhs) const; // subtract rhs
|
||||
Vector3& operator+=(const Vector3& rhs); // add rhs and update this object
|
||||
Vector3& operator-=(const Vector3& rhs); // subtract rhs and update this object
|
||||
Vector3 operator*(const float scale) const; // scale
|
||||
Vector3 operator*(const Vector3& rhs) const; // multiplay each element
|
||||
Vector3& operator*=(const float scale); // scale and update this object
|
||||
Vector3& operator*=(const Vector3& rhs); // product each element and update this object
|
||||
Vector3 operator/(const float scale) const; // inverse scale
|
||||
Vector3& operator/=(const float scale); // scale and update this object
|
||||
bool operator==(const Vector3& rhs) const; // exact compare, no epsilon
|
||||
bool operator!=(const Vector3& rhs) const; // exact compare, no epsilon
|
||||
bool operator<(const Vector3& rhs) const; // comparison for sort
|
||||
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||
float& operator[](int index); // subscript operator v[0], v[1]
|
||||
|
||||
friend Vector3 operator*(const float a, const Vector3 vec);
|
||||
friend std::ostream& operator<<(std::ostream& os, const Vector3& vec);
|
||||
friend Vector3 operator*(const float a, const Vector3 vec);
|
||||
friend std::ostream& operator<<(std::ostream& os, const Vector3& vec);
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 4D vector
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct Vector4
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
|
||||
// ctors
|
||||
Vector4() : x(0), y(0), z(0), w(0) {};
|
||||
Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {};
|
||||
// ctors
|
||||
Vector4() : x(0), y(0), z(0), w(0){};
|
||||
Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w){};
|
||||
|
||||
// utils functions
|
||||
void set(float x, float y, float z, float w);
|
||||
float length() const; //
|
||||
float distance(const Vector4& vec) const; // distance between two vectors
|
||||
Vector4& normalize(); //
|
||||
float dot(const Vector4& vec) const; // dot product
|
||||
bool equal(const Vector4& vec, float e) const; // compare with epsilon
|
||||
// utils functions
|
||||
void set(float x, float y, float z, float w);
|
||||
float length() const; //
|
||||
float distance(const Vector4& vec) const; // distance between two vectors
|
||||
Vector4& normalize(); //
|
||||
float dot(const Vector4& vec) const; // dot product
|
||||
bool equal(const Vector4& vec, float e) const; // compare with epsilon
|
||||
|
||||
// operators
|
||||
Vector4 operator-() const; // unary operator (negate)
|
||||
Vector4 operator+(const Vector4& rhs) const; // add rhs
|
||||
Vector4 operator-(const Vector4& rhs) const; // subtract rhs
|
||||
Vector4& operator+=(const Vector4& rhs); // add rhs and update this object
|
||||
Vector4& operator-=(const Vector4& rhs); // subtract rhs and update this object
|
||||
Vector4 operator*(const float scale) const; // scale
|
||||
Vector4 operator*(const Vector4& rhs) const; // multiply each element
|
||||
Vector4& operator*=(const float scale); // scale and update this object
|
||||
Vector4& operator*=(const Vector4& rhs); // multiply each element and update this object
|
||||
Vector4 operator/(const float scale) const; // inverse scale
|
||||
Vector4& operator/=(const float scale); // scale and update this object
|
||||
bool operator==(const Vector4& rhs) const; // exact compare, no epsilon
|
||||
bool operator!=(const Vector4& rhs) const; // exact compare, no epsilon
|
||||
bool operator<(const Vector4& rhs) const; // comparison for sort
|
||||
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||
float& operator[](int index); // subscript operator v[0], v[1]
|
||||
// operators
|
||||
Vector4 operator-() const; // unary operator (negate)
|
||||
Vector4 operator+(const Vector4& rhs) const; // add rhs
|
||||
Vector4 operator-(const Vector4& rhs) const; // subtract rhs
|
||||
Vector4& operator+=(const Vector4& rhs); // add rhs and update this object
|
||||
Vector4& operator-=(const Vector4& rhs); // subtract rhs and update this object
|
||||
Vector4 operator*(const float scale) const; // scale
|
||||
Vector4 operator*(const Vector4& rhs) const; // multiply each element
|
||||
Vector4& operator*=(const float scale); // scale and update this object
|
||||
Vector4& operator*=(const Vector4& rhs); // multiply each element and update this object
|
||||
Vector4 operator/(const float scale) const; // inverse scale
|
||||
Vector4& operator/=(const float scale); // scale and update this object
|
||||
bool operator==(const Vector4& rhs) const; // exact compare, no epsilon
|
||||
bool operator!=(const Vector4& rhs) const; // exact compare, no epsilon
|
||||
bool operator<(const Vector4& rhs) const; // comparison for sort
|
||||
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||
float& operator[](int index); // subscript operator v[0], v[1]
|
||||
|
||||
friend Vector4 operator*(const float a, const Vector4 vec);
|
||||
friend std::ostream& operator<<(std::ostream& os, const Vector4& vec);
|
||||
friend Vector4 operator*(const float a, const Vector4 vec);
|
||||
friend std::ostream& operator<<(std::ostream& os, const Vector4& vec);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// fast math routines from Doom3 SDK
|
||||
inline float invSqrt(float x)
|
||||
{
|
||||
float xhalf = 0.5f * x;
|
||||
int i = *(int*)&x; // get bits for floating value
|
||||
i = 0x5f3759df - (i>>1); // gives initial guess
|
||||
x = *(float*)&i; // convert bits back to float
|
||||
x = x * (1.5f - xhalf*x*x); // Newton step
|
||||
return x;
|
||||
float xhalf = 0.5f * x;
|
||||
int i = *(int*)&x; // get bits for floating value
|
||||
i = 0x5f3759df - (i >> 1); // gives initial guess
|
||||
x = *(float*)&i; // convert bits back to float
|
||||
x = x * (1.5f - xhalf * x * x); // Newton step
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// inline functions for Vector2
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline Vector2 Vector2::operator-() const {
|
||||
return Vector2(-x, -y);
|
||||
inline Vector2 Vector2::operator-() const
|
||||
{
|
||||
return Vector2(-x, -y);
|
||||
}
|
||||
|
||||
inline Vector2 Vector2::operator+(const Vector2& rhs) const {
|
||||
return Vector2(x+rhs.x, y+rhs.y);
|
||||
inline Vector2 Vector2::operator+(const Vector2& rhs) const
|
||||
{
|
||||
return Vector2(x + rhs.x, y + rhs.y);
|
||||
}
|
||||
|
||||
inline Vector2 Vector2::operator-(const Vector2& rhs) const {
|
||||
return Vector2(x-rhs.x, y-rhs.y);
|
||||
inline Vector2 Vector2::operator-(const Vector2& rhs) const
|
||||
{
|
||||
return Vector2(x - rhs.x, y - rhs.y);
|
||||
}
|
||||
|
||||
inline Vector2& Vector2::operator+=(const Vector2& rhs) {
|
||||
x += rhs.x; y += rhs.y; return *this;
|
||||
inline Vector2& Vector2::operator+=(const Vector2& rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector2& Vector2::operator-=(const Vector2& rhs) {
|
||||
x -= rhs.x; y -= rhs.y; return *this;
|
||||
inline Vector2& Vector2::operator-=(const Vector2& rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector2 Vector2::operator*(const float a) const {
|
||||
return Vector2(x*a, y*a);
|
||||
inline Vector2 Vector2::operator*(const float a) const
|
||||
{
|
||||
return Vector2(x * a, y * a);
|
||||
}
|
||||
|
||||
inline Vector2 Vector2::operator*(const Vector2& rhs) const {
|
||||
return Vector2(x*rhs.x, y*rhs.y);
|
||||
inline Vector2 Vector2::operator*(const Vector2& rhs) const
|
||||
{
|
||||
return Vector2(x * rhs.x, y * rhs.y);
|
||||
}
|
||||
|
||||
inline Vector2& Vector2::operator*=(const float a) {
|
||||
x *= a; y *= a; return *this;
|
||||
inline Vector2& Vector2::operator*=(const float a)
|
||||
{
|
||||
x *= a;
|
||||
y *= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector2& Vector2::operator*=(const Vector2& rhs) {
|
||||
x *= rhs.x; y *= rhs.y; return *this;
|
||||
inline Vector2& Vector2::operator*=(const Vector2& rhs)
|
||||
{
|
||||
x *= rhs.x;
|
||||
y *= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector2 Vector2::operator/(const float a) const {
|
||||
return Vector2(x/a, y/a);
|
||||
inline Vector2 Vector2::operator/(const float a) const
|
||||
{
|
||||
return Vector2(x / a, y / a);
|
||||
}
|
||||
|
||||
inline Vector2& Vector2::operator/=(const float a) {
|
||||
x /= a; y /= a; return *this;
|
||||
inline Vector2& Vector2::operator/=(const float a)
|
||||
{
|
||||
x /= a;
|
||||
y /= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool Vector2::operator==(const Vector2& rhs) const {
|
||||
return (x == rhs.x) && (y == rhs.y);
|
||||
inline bool Vector2::operator==(const Vector2& rhs) const
|
||||
{
|
||||
return (x == rhs.x) && (y == rhs.y);
|
||||
}
|
||||
|
||||
inline bool Vector2::operator!=(const Vector2& rhs) const {
|
||||
return (x != rhs.x) || (y != rhs.y);
|
||||
inline bool Vector2::operator!=(const Vector2& rhs) const
|
||||
{
|
||||
return (x != rhs.x) || (y != rhs.y);
|
||||
}
|
||||
|
||||
inline bool Vector2::operator<(const Vector2& rhs) const {
|
||||
if(x < rhs.x) return true;
|
||||
if(x > rhs.x) return false;
|
||||
if(y < rhs.y) return true;
|
||||
if(y > rhs.y) return false;
|
||||
return false;
|
||||
inline bool Vector2::operator<(const Vector2& rhs) const
|
||||
{
|
||||
if (x < rhs.x) return true;
|
||||
if (x > rhs.x) return false;
|
||||
if (y < rhs.y) return true;
|
||||
if (y > rhs.y) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline float Vector2::operator[](int index) const {
|
||||
return (&x)[index];
|
||||
inline float Vector2::operator[](int index) const
|
||||
{
|
||||
return (&x)[index];
|
||||
}
|
||||
|
||||
inline float& Vector2::operator[](int index) {
|
||||
return (&x)[index];
|
||||
inline float& Vector2::operator[](int index)
|
||||
{
|
||||
return (&x)[index];
|
||||
}
|
||||
|
||||
inline void Vector2::set(float x, float y) {
|
||||
this->x = x; this->y = y;
|
||||
inline void Vector2::set(float x, float y)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
inline float Vector2::length() const {
|
||||
return sqrtf(x*x + y*y);
|
||||
inline float Vector2::length() const
|
||||
{
|
||||
return sqrtf(x * x + y * y);
|
||||
}
|
||||
|
||||
inline float Vector2::distance(const Vector2& vec) const {
|
||||
return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y));
|
||||
inline float Vector2::distance(const Vector2& vec) const
|
||||
{
|
||||
return sqrtf((vec.x - x) * (vec.x - x) + (vec.y - y) * (vec.y - y));
|
||||
}
|
||||
|
||||
inline Vector2& Vector2::normalize() {
|
||||
//@@const float EPSILON = 0.000001f;
|
||||
float xxyy = x*x + y*y;
|
||||
//@@if(xxyy < EPSILON)
|
||||
//@@ return *this;
|
||||
inline Vector2& Vector2::normalize()
|
||||
{
|
||||
//@@const float EPSILON = 0.000001f;
|
||||
float xxyy = x * x + y * y;
|
||||
//@@if(xxyy < EPSILON)
|
||||
//@@ return *this;
|
||||
|
||||
//float invLength = invSqrt(xxyy);
|
||||
float invLength = 1.0f / sqrtf(xxyy);
|
||||
x *= invLength;
|
||||
y *= invLength;
|
||||
return *this;
|
||||
//float invLength = invSqrt(xxyy);
|
||||
float invLength = 1.0f / sqrtf(xxyy);
|
||||
x *= invLength;
|
||||
y *= invLength;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline float Vector2::dot(const Vector2& rhs) const {
|
||||
return (x*rhs.x + y*rhs.y);
|
||||
inline float Vector2::dot(const Vector2& rhs) const
|
||||
{
|
||||
return (x * rhs.x + y * rhs.y);
|
||||
}
|
||||
|
||||
inline bool Vector2::equal(const Vector2& rhs, float epsilon) const {
|
||||
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon;
|
||||
inline bool Vector2::equal(const Vector2& rhs, float epsilon) const
|
||||
{
|
||||
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon;
|
||||
}
|
||||
|
||||
inline Vector2 operator*(const float a, const Vector2 vec) {
|
||||
return Vector2(a*vec.x, a*vec.y);
|
||||
inline Vector2 operator*(const float a, const Vector2 vec)
|
||||
{
|
||||
return Vector2(a * vec.x, a * vec.y);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Vector2& vec) {
|
||||
os << "(" << vec.x << ", " << vec.y << ")";
|
||||
return os;
|
||||
inline std::ostream& operator<<(std::ostream& os, const Vector2& vec)
|
||||
{
|
||||
os << "(" << vec.x << ", " << vec.y << ")";
|
||||
return os;
|
||||
}
|
||||
// END OF VECTOR2 /////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// inline functions for Vector3
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline Vector3 Vector3::operator-() const {
|
||||
return Vector3(-x, -y, -z);
|
||||
inline Vector3 Vector3::operator-() const
|
||||
{
|
||||
return Vector3(-x, -y, -z);
|
||||
}
|
||||
|
||||
inline Vector3 Vector3::operator+(const Vector3& rhs) const {
|
||||
return Vector3(x+rhs.x, y+rhs.y, z+rhs.z);
|
||||
inline Vector3 Vector3::operator+(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3(x + rhs.x, y + rhs.y, z + rhs.z);
|
||||
}
|
||||
|
||||
inline Vector3 Vector3::operator-(const Vector3& rhs) const {
|
||||
return Vector3(x-rhs.x, y-rhs.y, z-rhs.z);
|
||||
inline Vector3 Vector3::operator-(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3(x - rhs.x, y - rhs.y, z - rhs.z);
|
||||
}
|
||||
|
||||
inline Vector3& Vector3::operator+=(const Vector3& rhs) {
|
||||
x += rhs.x; y += rhs.y; z += rhs.z; return *this;
|
||||
inline Vector3& Vector3::operator+=(const Vector3& rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
z += rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector3& Vector3::operator-=(const Vector3& rhs) {
|
||||
x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this;
|
||||
inline Vector3& Vector3::operator-=(const Vector3& rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
z -= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector3 Vector3::operator*(const float a) const {
|
||||
return Vector3(x*a, y*a, z*a);
|
||||
inline Vector3 Vector3::operator*(const float a) const
|
||||
{
|
||||
return Vector3(x * a, y * a, z * a);
|
||||
}
|
||||
|
||||
inline Vector3 Vector3::operator*(const Vector3& rhs) const {
|
||||
return Vector3(x*rhs.x, y*rhs.y, z*rhs.z);
|
||||
inline Vector3 Vector3::operator*(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3(x * rhs.x, y * rhs.y, z * rhs.z);
|
||||
}
|
||||
|
||||
inline Vector3& Vector3::operator*=(const float a) {
|
||||
x *= a; y *= a; z *= a; return *this;
|
||||
inline Vector3& Vector3::operator*=(const float a)
|
||||
{
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector3& Vector3::operator*=(const Vector3& rhs) {
|
||||
x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this;
|
||||
inline Vector3& Vector3::operator*=(const Vector3& rhs)
|
||||
{
|
||||
x *= rhs.x;
|
||||
y *= rhs.y;
|
||||
z *= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector3 Vector3::operator/(const float a) const {
|
||||
return Vector3(x/a, y/a, z/a);
|
||||
inline Vector3 Vector3::operator/(const float a) const
|
||||
{
|
||||
return Vector3(x / a, y / a, z / a);
|
||||
}
|
||||
|
||||
inline Vector3& Vector3::operator/=(const float a) {
|
||||
x /= a; y /= a; z /= a; return *this;
|
||||
inline Vector3& Vector3::operator/=(const float a)
|
||||
{
|
||||
x /= a;
|
||||
y /= a;
|
||||
z /= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool Vector3::operator==(const Vector3& rhs) const {
|
||||
return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
|
||||
inline bool Vector3::operator==(const Vector3& rhs) const
|
||||
{
|
||||
return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
|
||||
}
|
||||
|
||||
inline bool Vector3::operator!=(const Vector3& rhs) const {
|
||||
return (x != rhs.x) || (y != rhs.y) || (z != rhs.z);
|
||||
inline bool Vector3::operator!=(const Vector3& rhs) const
|
||||
{
|
||||
return (x != rhs.x) || (y != rhs.y) || (z != rhs.z);
|
||||
}
|
||||
|
||||
inline bool Vector3::operator<(const Vector3& rhs) const {
|
||||
if(x < rhs.x) return true;
|
||||
if(x > rhs.x) return false;
|
||||
if(y < rhs.y) return true;
|
||||
if(y > rhs.y) return false;
|
||||
if(z < rhs.z) return true;
|
||||
if(z > rhs.z) return false;
|
||||
return false;
|
||||
inline bool Vector3::operator<(const Vector3& rhs) const
|
||||
{
|
||||
if (x < rhs.x) return true;
|
||||
if (x > rhs.x) return false;
|
||||
if (y < rhs.y) return true;
|
||||
if (y > rhs.y) return false;
|
||||
if (z < rhs.z) return true;
|
||||
if (z > rhs.z) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline float Vector3::operator[](int index) const {
|
||||
return (&x)[index];
|
||||
inline float Vector3::operator[](int index) const
|
||||
{
|
||||
return (&x)[index];
|
||||
}
|
||||
|
||||
inline float& Vector3::operator[](int index) {
|
||||
return (&x)[index];
|
||||
inline float& Vector3::operator[](int index)
|
||||
{
|
||||
return (&x)[index];
|
||||
}
|
||||
|
||||
inline void Vector3::set(float x, float y, float z) {
|
||||
this->x = x; this->y = y; this->z = z;
|
||||
inline void Vector3::set(float x, float y, float z)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
inline float Vector3::length() const {
|
||||
return sqrtf(x*x + y*y + z*z);
|
||||
inline float Vector3::length() const
|
||||
{
|
||||
return sqrtf(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
inline float Vector3::distance(const Vector3& vec) const {
|
||||
return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z));
|
||||
inline float Vector3::distance(const Vector3& vec) const
|
||||
{
|
||||
return sqrtf((vec.x - x) * (vec.x - x) + (vec.y - y) * (vec.y - y) + (vec.z - z) * (vec.z - z));
|
||||
}
|
||||
|
||||
inline Vector3& Vector3::normalize() {
|
||||
//@@const float EPSILON = 0.000001f;
|
||||
float xxyyzz = x*x + y*y + z*z;
|
||||
//@@if(xxyyzz < EPSILON)
|
||||
//@@ return *this; // do nothing if it is ~zero vector
|
||||
inline Vector3& Vector3::normalize()
|
||||
{
|
||||
//@@const float EPSILON = 0.000001f;
|
||||
float xxyyzz = x * x + y * y + z * z;
|
||||
//@@if(xxyyzz < EPSILON)
|
||||
//@@ return *this; // do nothing if it is ~zero vector
|
||||
|
||||
//float invLength = invSqrt(xxyyzz);
|
||||
float invLength = 1.0f / sqrtf(xxyyzz);
|
||||
x *= invLength;
|
||||
y *= invLength;
|
||||
z *= invLength;
|
||||
return *this;
|
||||
//float invLength = invSqrt(xxyyzz);
|
||||
float invLength = 1.0f / sqrtf(xxyyzz);
|
||||
x *= invLength;
|
||||
y *= invLength;
|
||||
z *= invLength;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline float Vector3::dot(const Vector3& rhs) const {
|
||||
return (x*rhs.x + y*rhs.y + z*rhs.z);
|
||||
inline float Vector3::dot(const Vector3& rhs) const
|
||||
{
|
||||
return (x * rhs.x + y * rhs.y + z * rhs.z);
|
||||
}
|
||||
|
||||
inline Vector3 Vector3::cross(const Vector3& rhs) const {
|
||||
return Vector3(y*rhs.z - z*rhs.y, z*rhs.x - x*rhs.z, x*rhs.y - y*rhs.x);
|
||||
inline Vector3 Vector3::cross(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x);
|
||||
}
|
||||
|
||||
inline bool Vector3::equal(const Vector3& rhs, float epsilon) const {
|
||||
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && fabs(z - rhs.z) < epsilon;
|
||||
inline bool Vector3::equal(const Vector3& rhs, float epsilon) const
|
||||
{
|
||||
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && fabs(z - rhs.z) < epsilon;
|
||||
}
|
||||
|
||||
inline Vector3 operator*(const float a, const Vector3 vec) {
|
||||
return Vector3(a*vec.x, a*vec.y, a*vec.z);
|
||||
inline Vector3 operator*(const float a, const Vector3 vec)
|
||||
{
|
||||
return Vector3(a * vec.x, a * vec.y, a * vec.z);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Vector3& vec) {
|
||||
os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")";
|
||||
return os;
|
||||
inline std::ostream& operator<<(std::ostream& os, const Vector3& vec)
|
||||
{
|
||||
os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")";
|
||||
return os;
|
||||
}
|
||||
// END OF VECTOR3 /////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// inline functions for Vector4
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
inline Vector4 Vector4::operator-() const {
|
||||
return Vector4(-x, -y, -z, -w);
|
||||
inline Vector4 Vector4::operator-() const
|
||||
{
|
||||
return Vector4(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
inline Vector4 Vector4::operator+(const Vector4& rhs) const {
|
||||
return Vector4(x+rhs.x, y+rhs.y, z+rhs.z, w+rhs.w);
|
||||
inline Vector4 Vector4::operator+(const Vector4& rhs) const
|
||||
{
|
||||
return Vector4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w);
|
||||
}
|
||||
|
||||
inline Vector4 Vector4::operator-(const Vector4& rhs) const {
|
||||
return Vector4(x-rhs.x, y-rhs.y, z-rhs.z, w-rhs.w);
|
||||
inline Vector4 Vector4::operator-(const Vector4& rhs) const
|
||||
{
|
||||
return Vector4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w);
|
||||
}
|
||||
|
||||
inline Vector4& Vector4::operator+=(const Vector4& rhs) {
|
||||
x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this;
|
||||
inline Vector4& Vector4::operator+=(const Vector4& rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
z += rhs.z;
|
||||
w += rhs.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4& Vector4::operator-=(const Vector4& rhs) {
|
||||
x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this;
|
||||
inline Vector4& Vector4::operator-=(const Vector4& rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
z -= rhs.z;
|
||||
w -= rhs.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4 Vector4::operator*(const float a) const {
|
||||
return Vector4(x*a, y*a, z*a, w*a);
|
||||
inline Vector4 Vector4::operator*(const float a) const
|
||||
{
|
||||
return Vector4(x * a, y * a, z * a, w * a);
|
||||
}
|
||||
|
||||
inline Vector4 Vector4::operator*(const Vector4& rhs) const {
|
||||
return Vector4(x*rhs.x, y*rhs.y, z*rhs.z, w*rhs.w);
|
||||
inline Vector4 Vector4::operator*(const Vector4& rhs) const
|
||||
{
|
||||
return Vector4(x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w);
|
||||
}
|
||||
|
||||
inline Vector4& Vector4::operator*=(const float a) {
|
||||
x *= a; y *= a; z *= a; w *= a; return *this;
|
||||
inline Vector4& Vector4::operator*=(const float a)
|
||||
{
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
w *= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4& Vector4::operator*=(const Vector4& rhs) {
|
||||
x *= rhs.x; y *= rhs.y; z *= rhs.z; w *= rhs.w; return *this;
|
||||
inline Vector4& Vector4::operator*=(const Vector4& rhs)
|
||||
{
|
||||
x *= rhs.x;
|
||||
y *= rhs.y;
|
||||
z *= rhs.z;
|
||||
w *= rhs.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector4 Vector4::operator/(const float a) const {
|
||||
return Vector4(x/a, y/a, z/a, w/a);
|
||||
inline Vector4 Vector4::operator/(const float a) const
|
||||
{
|
||||
return Vector4(x / a, y / a, z / a, w / a);
|
||||
}
|
||||
|
||||
inline Vector4& Vector4::operator/=(const float a) {
|
||||
x /= a; y /= a; z /= a; w /= a; return *this;
|
||||
inline Vector4& Vector4::operator/=(const float a)
|
||||
{
|
||||
x /= a;
|
||||
y /= a;
|
||||
z /= a;
|
||||
w /= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool Vector4::operator==(const Vector4& rhs) const {
|
||||
return (x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w);
|
||||
inline bool Vector4::operator==(const Vector4& rhs) const
|
||||
{
|
||||
return (x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w);
|
||||
}
|
||||
|
||||
inline bool Vector4::operator!=(const Vector4& rhs) const {
|
||||
return (x != rhs.x) || (y != rhs.y) || (z != rhs.z) || (w != rhs.w);
|
||||
inline bool Vector4::operator!=(const Vector4& rhs) const
|
||||
{
|
||||
return (x != rhs.x) || (y != rhs.y) || (z != rhs.z) || (w != rhs.w);
|
||||
}
|
||||
|
||||
inline bool Vector4::operator<(const Vector4& rhs) const {
|
||||
if(x < rhs.x) return true;
|
||||
if(x > rhs.x) return false;
|
||||
if(y < rhs.y) return true;
|
||||
if(y > rhs.y) return false;
|
||||
if(z < rhs.z) return true;
|
||||
if(z > rhs.z) return false;
|
||||
if(w < rhs.w) return true;
|
||||
if(w > rhs.w) return false;
|
||||
return false;
|
||||
inline bool Vector4::operator<(const Vector4& rhs) const
|
||||
{
|
||||
if (x < rhs.x) return true;
|
||||
if (x > rhs.x) return false;
|
||||
if (y < rhs.y) return true;
|
||||
if (y > rhs.y) return false;
|
||||
if (z < rhs.z) return true;
|
||||
if (z > rhs.z) return false;
|
||||
if (w < rhs.w) return true;
|
||||
if (w > rhs.w) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline float Vector4::operator[](int index) const {
|
||||
return (&x)[index];
|
||||
inline float Vector4::operator[](int index) const
|
||||
{
|
||||
return (&x)[index];
|
||||
}
|
||||
|
||||
inline float& Vector4::operator[](int index) {
|
||||
return (&x)[index];
|
||||
inline float& Vector4::operator[](int index)
|
||||
{
|
||||
return (&x)[index];
|
||||
}
|
||||
|
||||
inline void Vector4::set(float x, float y, float z, float w) {
|
||||
this->x = x; this->y = y; this->z = z; this->w = w;
|
||||
inline void Vector4::set(float x, float y, float z, float w)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
this->w = w;
|
||||
}
|
||||
|
||||
inline float Vector4::length() const {
|
||||
return sqrtf(x*x + y*y + z*z + w*w);
|
||||
inline float Vector4::length() const
|
||||
{
|
||||
return sqrtf(x * x + y * y + z * z + w * w);
|
||||
}
|
||||
|
||||
inline float Vector4::distance(const Vector4& vec) const {
|
||||
return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z) + (vec.w-w)*(vec.w-w));
|
||||
inline float Vector4::distance(const Vector4& vec) const
|
||||
{
|
||||
return sqrtf((vec.x - x) * (vec.x - x) + (vec.y - y) * (vec.y - y) + (vec.z - z) * (vec.z - z) + (vec.w - w) * (vec.w - w));
|
||||
}
|
||||
|
||||
inline Vector4& Vector4::normalize() {
|
||||
//NOTE: leave w-component untouched
|
||||
//@@const float EPSILON = 0.000001f;
|
||||
float xxyyzz = x*x + y*y + z*z;
|
||||
//@@if(xxyyzz < EPSILON)
|
||||
//@@ return *this; // do nothing if it is zero vector
|
||||
inline Vector4& Vector4::normalize()
|
||||
{
|
||||
//NOTE: leave w-component untouched
|
||||
//@@const float EPSILON = 0.000001f;
|
||||
float xxyyzz = x * x + y * y + z * z;
|
||||
//@@if(xxyyzz < EPSILON)
|
||||
//@@ return *this; // do nothing if it is zero vector
|
||||
|
||||
//float invLength = invSqrt(xxyyzz);
|
||||
float invLength = 1.0f / sqrtf(xxyyzz);
|
||||
x *= invLength;
|
||||
y *= invLength;
|
||||
z *= invLength;
|
||||
return *this;
|
||||
//float invLength = invSqrt(xxyyzz);
|
||||
float invLength = 1.0f / sqrtf(xxyyzz);
|
||||
x *= invLength;
|
||||
y *= invLength;
|
||||
z *= invLength;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline float Vector4::dot(const Vector4& rhs) const {
|
||||
return (x*rhs.x + y*rhs.y + z*rhs.z + w*rhs.w);
|
||||
inline float Vector4::dot(const Vector4& rhs) const
|
||||
{
|
||||
return (x * rhs.x + y * rhs.y + z * rhs.z + w * rhs.w);
|
||||
}
|
||||
|
||||
inline bool Vector4::equal(const Vector4& rhs, float epsilon) const {
|
||||
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon &&
|
||||
fabs(z - rhs.z) < epsilon && fabs(w - rhs.w) < epsilon;
|
||||
inline bool Vector4::equal(const Vector4& rhs, float epsilon) const
|
||||
{
|
||||
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon &&
|
||||
fabs(z - rhs.z) < epsilon && fabs(w - rhs.w) < epsilon;
|
||||
}
|
||||
|
||||
inline Vector4 operator*(const float a, const Vector4 vec) {
|
||||
return Vector4(a*vec.x, a*vec.y, a*vec.z, a*vec.w);
|
||||
inline Vector4 operator*(const float a, const Vector4 vec)
|
||||
{
|
||||
return Vector4(a * vec.x, a * vec.y, a * vec.z, a * vec.w);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Vector4& vec) {
|
||||
os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w << ")";
|
||||
return os;
|
||||
inline std::ostream& operator<<(std::ostream& os, const Vector4& vec)
|
||||
{
|
||||
os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w << ")";
|
||||
return os;
|
||||
}
|
||||
// END OF VECTOR4 /////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
#include <cstdbool>
|
||||
#include <unistd.h>
|
||||
|
||||
#define sprintf_s snprintf
|
||||
#define vsprintf_s sprintf
|
||||
#define _stricmp strcmp
|
||||
#define stricmp strcmp
|
||||
#define strnicmp strncasecmp
|
||||
#define strcpy_s(dst, n, src) int(strncpy(dst, src, n) != nullptr)
|
||||
#define sprintf_s snprintf
|
||||
#define vsprintf_s sprintf
|
||||
#define _stricmp strcmp
|
||||
#define stricmp strcmp
|
||||
#define strnicmp strncasecmp
|
||||
#define strcpy_s(dst, n, src) int(strncpy(dst, src, n) != nullptr)
|
||||
#define fopen_s(fd, path, mode) int((*fd = fopen(path, mode)) != nullptr)
|
||||
#define _vsnprintf_s(buffer, size, fmt, ap) vsnprintf(buffer, size, fmt, ap)
|
||||
#define _vsnprintf_s(buffer, size, fmt, ap) vsnprintf(buffer, size, fmt, ap)
|
||||
#define OutputDebugStringA(x) fprintf(stderr, "%s\n", x)
|
||||
|
||||
typedef int errno_t;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -86,11 +86,11 @@ source files with custom allocators.*/
|
||||
/*The PNG color types (also used for raw).*/
|
||||
typedef enum LodePNGColorType
|
||||
{
|
||||
LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/
|
||||
LCT_RGB = 2, /*RGB: 8,16 bit*/
|
||||
LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/
|
||||
LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/
|
||||
LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/
|
||||
LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/
|
||||
LCT_RGB = 2, /*RGB: 8,16 bit*/
|
||||
LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/
|
||||
LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/
|
||||
LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/
|
||||
} LodePNGColorType;
|
||||
|
||||
#ifdef LODEPNG_COMPILE_DECODER
|
||||
@@ -110,16 +110,16 @@ bitdepth: the desired bit depth for the raw output image. See explanation on PNG
|
||||
Return value: LodePNG error code (0 means no error).
|
||||
*/
|
||||
unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const unsigned char* in, size_t insize,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
const unsigned char* in, size_t insize,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
|
||||
/*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/
|
||||
unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const unsigned char* in, size_t insize);
|
||||
const unsigned char* in, size_t insize);
|
||||
|
||||
/*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/
|
||||
unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const unsigned char* in, size_t insize);
|
||||
const unsigned char* in, size_t insize);
|
||||
|
||||
#ifdef LODEPNG_COMPILE_DISK
|
||||
/*
|
||||
@@ -127,20 +127,19 @@ Load PNG from disk, from file with given name.
|
||||
Same as the other decode functions, but instead takes a filename as input.
|
||||
*/
|
||||
unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const char* filename,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
const char* filename,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
|
||||
/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/
|
||||
unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const char* filename);
|
||||
const char* filename);
|
||||
|
||||
/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/
|
||||
unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const char* filename);
|
||||
const char* filename);
|
||||
#endif /*LODEPNG_COMPILE_DISK*/
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
/*
|
||||
Converts raw pixel data into a PNG image in memory. The colortype and bitdepth
|
||||
@@ -159,16 +158,16 @@ bitdepth: the bit depth of the raw input image. See explanation on PNG color typ
|
||||
Return value: LodePNG error code (0 means no error).
|
||||
*/
|
||||
unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize,
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
|
||||
/*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/
|
||||
unsigned lodepng_encode32(unsigned char** out, size_t* outsize,
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
|
||||
/*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/
|
||||
unsigned lodepng_encode24(unsigned char** out, size_t* outsize,
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
|
||||
#ifdef LODEPNG_COMPILE_DISK
|
||||
/*
|
||||
@@ -177,20 +176,19 @@ Same as the other encode functions, but instead takes a filename as output.
|
||||
NOTE: This overwrites existing files without warning!
|
||||
*/
|
||||
unsigned lodepng_encode_file(const char* filename,
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
|
||||
/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/
|
||||
unsigned lodepng_encode32_file(const char* filename,
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
|
||||
/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/
|
||||
unsigned lodepng_encode24_file(const char* filename,
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
#endif /*LODEPNG_COMPILE_DISK*/
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
|
||||
|
||||
#ifdef LODEPNG_COMPILE_CPP
|
||||
namespace lodepng
|
||||
{
|
||||
@@ -198,31 +196,31 @@ namespace lodepng
|
||||
/*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype
|
||||
is the format to output the pixels to. Default is RGBA 8-bit per channel.*/
|
||||
unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
|
||||
const unsigned char* in, size_t insize,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
const unsigned char* in, size_t insize,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
|
||||
const std::vector<unsigned char>& in,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
const std::vector<unsigned char>& in,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
#ifdef LODEPNG_COMPILE_DISK
|
||||
/*
|
||||
Converts PNG file from disk to raw pixel data in memory.
|
||||
Same as the other decode functions, but instead takes a filename as input.
|
||||
*/
|
||||
unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
|
||||
const std::string& filename,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
#endif //LODEPNG_COMPILE_DISK
|
||||
#endif //LODEPNG_COMPILE_DECODER
|
||||
const std::string& filename,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
#endif //LODEPNG_COMPILE_DISK
|
||||
#endif //LODEPNG_COMPILE_DECODER
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
/*Same as lodepng_encode_memory, but encodes to an std::vector. colortype
|
||||
is that of the raw input data. The output PNG color type will be auto chosen.*/
|
||||
unsigned encode(std::vector<unsigned char>& out,
|
||||
const unsigned char* in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
const unsigned char* in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
unsigned encode(std::vector<unsigned char>& out,
|
||||
const std::vector<unsigned char>& in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
const std::vector<unsigned char>& in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
#ifdef LODEPNG_COMPILE_DISK
|
||||
/*
|
||||
Converts 32-bit RGBA raw pixel data into a PNG file on disk.
|
||||
@@ -230,14 +228,14 @@ Same as the other encode functions, but instead takes a filename as output.
|
||||
NOTE: This overwrites existing files without warning!
|
||||
*/
|
||||
unsigned encode(const std::string& filename,
|
||||
const unsigned char* in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
const unsigned char* in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
unsigned encode(const std::string& filename,
|
||||
const std::vector<unsigned char>& in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
#endif //LODEPNG_COMPILE_DISK
|
||||
#endif //LODEPNG_COMPILE_ENCODER
|
||||
} //namespace lodepng
|
||||
const std::vector<unsigned char>& in, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
|
||||
#endif //LODEPNG_COMPILE_DISK
|
||||
#endif //LODEPNG_COMPILE_ENCODER
|
||||
} //namespace lodepng
|
||||
#endif /*LODEPNG_COMPILE_CPP*/
|
||||
#endif /*LODEPNG_COMPILE_PNG*/
|
||||
|
||||
@@ -251,20 +249,20 @@ const char* lodepng_error_text(unsigned code);
|
||||
typedef struct LodePNGDecompressSettings LodePNGDecompressSettings;
|
||||
struct LodePNGDecompressSettings
|
||||
{
|
||||
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
|
||||
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
|
||||
|
||||
/*use custom zlib decoder instead of built in one (default: null)*/
|
||||
unsigned (*custom_zlib)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGDecompressSettings*);
|
||||
/*use custom deflate decoder instead of built in one (default: null)
|
||||
/*use custom zlib decoder instead of built in one (default: null)*/
|
||||
unsigned (*custom_zlib)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGDecompressSettings*);
|
||||
/*use custom deflate decoder instead of built in one (default: null)
|
||||
if custom_zlib is used, custom_deflate is ignored since only the built in
|
||||
zlib function will call custom_deflate*/
|
||||
unsigned (*custom_inflate)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGDecompressSettings*);
|
||||
unsigned (*custom_inflate)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGDecompressSettings*);
|
||||
|
||||
const void* custom_context; /*optional custom settings for custom functions*/
|
||||
const void* custom_context; /*optional custom settings for custom functions*/
|
||||
};
|
||||
|
||||
extern const LodePNGDecompressSettings lodepng_default_decompress_settings;
|
||||
@@ -279,26 +277,26 @@ between speed and compression ratio.
|
||||
typedef struct LodePNGCompressSettings LodePNGCompressSettings;
|
||||
struct LodePNGCompressSettings /*deflate = compress*/
|
||||
{
|
||||
/*LZ77 related settings*/
|
||||
unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/
|
||||
unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/
|
||||
unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/
|
||||
unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/
|
||||
unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/
|
||||
unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/
|
||||
/*LZ77 related settings*/
|
||||
unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/
|
||||
unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/
|
||||
unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/
|
||||
unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/
|
||||
unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/
|
||||
unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/
|
||||
|
||||
/*use custom zlib encoder instead of built in one (default: null)*/
|
||||
unsigned (*custom_zlib)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGCompressSettings*);
|
||||
/*use custom deflate encoder instead of built in one (default: null)
|
||||
/*use custom zlib encoder instead of built in one (default: null)*/
|
||||
unsigned (*custom_zlib)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGCompressSettings*);
|
||||
/*use custom deflate encoder instead of built in one (default: null)
|
||||
if custom_zlib is used, custom_deflate is ignored since only the built in
|
||||
zlib function will call custom_deflate*/
|
||||
unsigned (*custom_deflate)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGCompressSettings*);
|
||||
unsigned (*custom_deflate)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGCompressSettings*);
|
||||
|
||||
const void* custom_context; /*optional custom settings for custom functions*/
|
||||
const void* custom_context; /*optional custom settings for custom functions*/
|
||||
};
|
||||
|
||||
extern const LodePNGCompressSettings lodepng_default_compress_settings;
|
||||
@@ -313,11 +311,11 @@ format, and is used both for PNG and raw image data in LodePNG.
|
||||
*/
|
||||
typedef struct LodePNGColorMode
|
||||
{
|
||||
/*header (IHDR)*/
|
||||
LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/
|
||||
unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/
|
||||
/*header (IHDR)*/
|
||||
LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/
|
||||
unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/
|
||||
|
||||
/*
|
||||
/*
|
||||
palette (PLTE and tRNS)
|
||||
|
||||
Dynamically allocated with the colors of the palette, including alpha.
|
||||
@@ -330,10 +328,10 @@ typedef struct LodePNGColorMode
|
||||
|
||||
The palette is only supported for color type 3.
|
||||
*/
|
||||
unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/
|
||||
size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/
|
||||
unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/
|
||||
size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/
|
||||
|
||||
/*
|
||||
/*
|
||||
transparent color key (tRNS)
|
||||
|
||||
This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit.
|
||||
@@ -344,10 +342,10 @@ typedef struct LodePNGColorMode
|
||||
|
||||
The color key is only supported for color types 0 and 2.
|
||||
*/
|
||||
unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/
|
||||
unsigned key_r; /*red/greyscale component of color key*/
|
||||
unsigned key_g; /*green component of color key*/
|
||||
unsigned key_b; /*blue component of color key*/
|
||||
unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/
|
||||
unsigned key_r; /*red/greyscale component of color key*/
|
||||
unsigned key_g; /*green component of color key*/
|
||||
unsigned key_b; /*blue component of color key*/
|
||||
} LodePNGColorMode;
|
||||
|
||||
/*init, cleanup and copy functions to use with this struct*/
|
||||
@@ -359,7 +357,7 @@ unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode*
|
||||
void lodepng_palette_clear(LodePNGColorMode* info);
|
||||
/*add 1 color to the palette*/
|
||||
unsigned lodepng_palette_add(LodePNGColorMode* info,
|
||||
unsigned char r, unsigned char g, unsigned char b, unsigned char a);
|
||||
unsigned char r, unsigned char g, unsigned char b, unsigned char a);
|
||||
|
||||
/*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/
|
||||
unsigned lodepng_get_bpp(const LodePNGColorMode* info);
|
||||
@@ -390,26 +388,26 @@ size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* colo
|
||||
/*The information of a Time chunk in PNG.*/
|
||||
typedef struct LodePNGTime
|
||||
{
|
||||
unsigned year; /*2 bytes used (0-65535)*/
|
||||
unsigned month; /*1-12*/
|
||||
unsigned day; /*1-31*/
|
||||
unsigned hour; /*0-23*/
|
||||
unsigned minute; /*0-59*/
|
||||
unsigned second; /*0-60 (to allow for leap seconds)*/
|
||||
unsigned year; /*2 bytes used (0-65535)*/
|
||||
unsigned month; /*1-12*/
|
||||
unsigned day; /*1-31*/
|
||||
unsigned hour; /*0-23*/
|
||||
unsigned minute; /*0-59*/
|
||||
unsigned second; /*0-60 (to allow for leap seconds)*/
|
||||
} LodePNGTime;
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
|
||||
/*Information about the PNG image, except pixels, width and height.*/
|
||||
typedef struct LodePNGInfo
|
||||
{
|
||||
/*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/
|
||||
unsigned compression_method;/*compression method of the original file. Always 0.*/
|
||||
unsigned filter_method; /*filter method of the original file*/
|
||||
unsigned interlace_method; /*interlace method of the original file*/
|
||||
LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/
|
||||
/*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/
|
||||
unsigned compression_method; /*compression method of the original file. Always 0.*/
|
||||
unsigned filter_method; /*filter method of the original file*/
|
||||
unsigned interlace_method; /*interlace method of the original file*/
|
||||
LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
/*
|
||||
/*
|
||||
suggested background color chunk (bKGD)
|
||||
This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit.
|
||||
|
||||
@@ -420,12 +418,12 @@ typedef struct LodePNGInfo
|
||||
|
||||
The decoder does not use this background color to edit the color of pixels.
|
||||
*/
|
||||
unsigned background_defined; /*is a suggested background color given?*/
|
||||
unsigned background_r; /*red component of suggested background color*/
|
||||
unsigned background_g; /*green component of suggested background color*/
|
||||
unsigned background_b; /*blue component of suggested background color*/
|
||||
unsigned background_defined; /*is a suggested background color given?*/
|
||||
unsigned background_r; /*red component of suggested background color*/
|
||||
unsigned background_g; /*green component of suggested background color*/
|
||||
unsigned background_b; /*blue component of suggested background color*/
|
||||
|
||||
/*
|
||||
/*
|
||||
non-international text chunks (tEXt and zTXt)
|
||||
|
||||
The char** arrays each contain num strings. The actual messages are in
|
||||
@@ -438,32 +436,32 @@ typedef struct LodePNGInfo
|
||||
Don't allocate these text buffers yourself. Use the init/cleanup functions
|
||||
correctly and use lodepng_add_text and lodepng_clear_text.
|
||||
*/
|
||||
size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/
|
||||
char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/
|
||||
char** text_strings; /*the actual text*/
|
||||
size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/
|
||||
char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/
|
||||
char** text_strings; /*the actual text*/
|
||||
|
||||
/*
|
||||
/*
|
||||
international text chunks (iTXt)
|
||||
Similar to the non-international text chunks, but with additional strings
|
||||
"langtags" and "transkeys".
|
||||
*/
|
||||
size_t itext_num; /*the amount of international texts in this PNG*/
|
||||
char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/
|
||||
char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/
|
||||
char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/
|
||||
char** itext_strings; /*the actual international text - UTF-8 string*/
|
||||
size_t itext_num; /*the amount of international texts in this PNG*/
|
||||
char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/
|
||||
char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/
|
||||
char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/
|
||||
char** itext_strings; /*the actual international text - UTF-8 string*/
|
||||
|
||||
/*time chunk (tIME)*/
|
||||
unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/
|
||||
LodePNGTime time;
|
||||
/*time chunk (tIME)*/
|
||||
unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/
|
||||
LodePNGTime time;
|
||||
|
||||
/*phys chunk (pHYs)*/
|
||||
unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/
|
||||
unsigned phys_x; /*pixels per unit in x direction*/
|
||||
unsigned phys_y; /*pixels per unit in y direction*/
|
||||
unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
|
||||
/*phys chunk (pHYs)*/
|
||||
unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/
|
||||
unsigned phys_x; /*pixels per unit in x direction*/
|
||||
unsigned phys_y; /*pixels per unit in y direction*/
|
||||
unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
|
||||
|
||||
/*
|
||||
/*
|
||||
unknown chunks
|
||||
There are 3 buffers, one for each position in the PNG where unknown chunks can appear
|
||||
each buffer contains all unknown chunks for that position consecutively
|
||||
@@ -472,9 +470,9 @@ typedef struct LodePNGInfo
|
||||
Do not allocate or traverse this data yourself. Use the chunk traversing functions declared
|
||||
later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct.
|
||||
*/
|
||||
unsigned char* unknown_chunks_data[3];
|
||||
size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
unsigned char* unknown_chunks_data[3];
|
||||
size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
} LodePNGInfo;
|
||||
|
||||
/*init, cleanup and copy functions to use with this struct*/
|
||||
@@ -484,13 +482,13 @@ void lodepng_info_cleanup(LodePNGInfo* info);
|
||||
unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source);
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
|
||||
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
|
||||
unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/
|
||||
|
||||
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
|
||||
unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
|
||||
const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
|
||||
/*
|
||||
Converts raw buffer from one color type to another color type, based on
|
||||
@@ -504,8 +502,8 @@ For 16-bit per channel colors, uses big endian format like PNG does.
|
||||
Return value is LodePNG error code
|
||||
*/
|
||||
unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
|
||||
LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in,
|
||||
unsigned w, unsigned h);
|
||||
LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in,
|
||||
unsigned w, unsigned h);
|
||||
|
||||
#ifdef LODEPNG_COMPILE_DECODER
|
||||
/*
|
||||
@@ -514,16 +512,16 @@ decoder, but not the Info settings from the Info structs.
|
||||
*/
|
||||
typedef struct LodePNGDecoderSettings
|
||||
{
|
||||
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
|
||||
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
|
||||
|
||||
unsigned ignore_crc; /*ignore CRC checksums*/
|
||||
unsigned ignore_crc; /*ignore CRC checksums*/
|
||||
|
||||
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
|
||||
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/
|
||||
/*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/
|
||||
unsigned remember_unknown_chunks;
|
||||
unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/
|
||||
/*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/
|
||||
unsigned remember_unknown_chunks;
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
} LodePNGDecoderSettings;
|
||||
|
||||
@@ -534,101 +532,100 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings);
|
||||
/*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/
|
||||
typedef enum LodePNGFilterStrategy
|
||||
{
|
||||
/*every filter at zero*/
|
||||
LFS_ZERO,
|
||||
/*Use filter that gives minumum sum, as described in the official PNG filter heuristic.*/
|
||||
LFS_MINSUM,
|
||||
/*Use the filter type that gives smallest Shannon entropy for this scanline. Depending
|
||||
/*every filter at zero*/
|
||||
LFS_ZERO,
|
||||
/*Use filter that gives minumum sum, as described in the official PNG filter heuristic.*/
|
||||
LFS_MINSUM,
|
||||
/*Use the filter type that gives smallest Shannon entropy for this scanline. Depending
|
||||
on the image, this is better or worse than minsum.*/
|
||||
LFS_ENTROPY,
|
||||
/*
|
||||
LFS_ENTROPY,
|
||||
/*
|
||||
Brute-force-search PNG filters by compressing each filter for each scanline.
|
||||
Experimental, very slow, and only rarely gives better compression than MINSUM.
|
||||
*/
|
||||
LFS_BRUTE_FORCE,
|
||||
/*use predefined_filters buffer: you specify the filter type for each scanline*/
|
||||
LFS_PREDEFINED
|
||||
LFS_BRUTE_FORCE,
|
||||
/*use predefined_filters buffer: you specify the filter type for each scanline*/
|
||||
LFS_PREDEFINED
|
||||
} LodePNGFilterStrategy;
|
||||
|
||||
/*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding.
|
||||
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/
|
||||
typedef struct LodePNGColorProfile
|
||||
{
|
||||
unsigned colored; /*not greyscale*/
|
||||
unsigned key; /*if true, image is not opaque. Only if true and alpha is false, color key is possible.*/
|
||||
unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/
|
||||
unsigned short key_g;
|
||||
unsigned short key_b;
|
||||
unsigned alpha; /*alpha channel or alpha palette required*/
|
||||
unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/
|
||||
unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/
|
||||
unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/
|
||||
unsigned colored; /*not greyscale*/
|
||||
unsigned key; /*if true, image is not opaque. Only if true and alpha is false, color key is possible.*/
|
||||
unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/
|
||||
unsigned short key_g;
|
||||
unsigned short key_b;
|
||||
unsigned alpha; /*alpha channel or alpha palette required*/
|
||||
unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/
|
||||
unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/
|
||||
unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/
|
||||
} LodePNGColorProfile;
|
||||
|
||||
void lodepng_color_profile_init(LodePNGColorProfile* profile);
|
||||
|
||||
/*Get a LodePNGColorProfile of the image.*/
|
||||
unsigned get_color_profile(LodePNGColorProfile* profile,
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
const LodePNGColorMode* mode_in);
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
const LodePNGColorMode* mode_in);
|
||||
/*The function LodePNG uses internally to decide the PNG color with auto_convert.
|
||||
Chooses an optimal color model, e.g. grey if only grey pixels, palette if < 256 colors, ...*/
|
||||
unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out,
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
const LodePNGColorMode* mode_in);
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
const LodePNGColorMode* mode_in);
|
||||
|
||||
/*Settings for the encoder.*/
|
||||
typedef struct LodePNGEncoderSettings
|
||||
{
|
||||
LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/
|
||||
LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/
|
||||
|
||||
unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/
|
||||
unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/
|
||||
|
||||
/*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than
|
||||
/*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than
|
||||
8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to
|
||||
completely follow the official PNG heuristic, filter_palette_zero must be true and
|
||||
filter_strategy must be LFS_MINSUM*/
|
||||
unsigned filter_palette_zero;
|
||||
/*Which filter strategy to use when not using zeroes due to filter_palette_zero.
|
||||
unsigned filter_palette_zero;
|
||||
/*Which filter strategy to use when not using zeroes due to filter_palette_zero.
|
||||
Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/
|
||||
LodePNGFilterStrategy filter_strategy;
|
||||
/*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with
|
||||
LodePNGFilterStrategy filter_strategy;
|
||||
/*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with
|
||||
the same length as the amount of scanlines in the image, and each value must <= 5. You
|
||||
have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero
|
||||
must be set to 0 to ensure this is also used on palette or low bitdepth images.*/
|
||||
const unsigned char* predefined_filters;
|
||||
const unsigned char* predefined_filters;
|
||||
|
||||
/*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette).
|
||||
/*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette).
|
||||
If colortype is 3, PLTE is _always_ created.*/
|
||||
unsigned force_palette;
|
||||
unsigned force_palette;
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
/*add LodePNG identifier and version as a text chunk, for debugging*/
|
||||
unsigned add_id;
|
||||
/*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/
|
||||
unsigned text_compression;
|
||||
/*add LodePNG identifier and version as a text chunk, for debugging*/
|
||||
unsigned add_id;
|
||||
/*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/
|
||||
unsigned text_compression;
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
} LodePNGEncoderSettings;
|
||||
|
||||
void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings);
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
|
||||
|
||||
#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
|
||||
/*The settings, state and information for extended encoding and decoding.*/
|
||||
typedef struct LodePNGState
|
||||
{
|
||||
#ifdef LODEPNG_COMPILE_DECODER
|
||||
LodePNGDecoderSettings decoder; /*the decoding settings*/
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
LodePNGDecoderSettings decoder; /*the decoding settings*/
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
LodePNGEncoderSettings encoder; /*the encoding settings*/
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/
|
||||
LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/
|
||||
unsigned error;
|
||||
LodePNGEncoderSettings encoder; /*the encoding settings*/
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/
|
||||
LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/
|
||||
unsigned error;
|
||||
#ifdef LODEPNG_COMPILE_CPP
|
||||
//For the lodepng::State subclass.
|
||||
virtual ~LodePNGState(){}
|
||||
//For the lodepng::State subclass.
|
||||
virtual ~LodePNGState() {}
|
||||
#endif
|
||||
} LodePNGState;
|
||||
|
||||
@@ -644,8 +641,8 @@ Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings
|
||||
getting much more information about the PNG image and color mode.
|
||||
*/
|
||||
unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
|
||||
LodePNGState* state,
|
||||
const unsigned char* in, size_t insize);
|
||||
LodePNGState* state,
|
||||
const unsigned char* in, size_t insize);
|
||||
|
||||
/*
|
||||
Read the PNG header, but not the actual data. This returns only the information
|
||||
@@ -653,16 +650,15 @@ that is in the header chunk of the PNG, such as width, height and color type. Th
|
||||
information is placed in the info_png field of the LodePNGState.
|
||||
*/
|
||||
unsigned lodepng_inspect(unsigned* w, unsigned* h,
|
||||
LodePNGState* state,
|
||||
const unsigned char* in, size_t insize);
|
||||
LodePNGState* state,
|
||||
const unsigned char* in, size_t insize);
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/
|
||||
unsigned lodepng_encode(unsigned char** out, size_t* outsize,
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
LodePNGState* state);
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
LodePNGState* state);
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
|
||||
/*
|
||||
@@ -723,14 +719,12 @@ The out variable and outlength are updated to reflect the new reallocated buffer
|
||||
Returne error code (0 if it went ok)
|
||||
*/
|
||||
unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length,
|
||||
const char* type, const unsigned char* data);
|
||||
|
||||
const char* type, const unsigned char* data);
|
||||
|
||||
/*Calculate CRC32 of buffer*/
|
||||
unsigned lodepng_crc32(const unsigned char* buf, size_t len);
|
||||
#endif /*LODEPNG_COMPILE_PNG*/
|
||||
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ZLIB
|
||||
/*
|
||||
This zlib part can be used independently to zlib compress and decompress a
|
||||
@@ -741,8 +735,8 @@ part of zlib that is required for PNG, it does not support dictionaries.
|
||||
#ifdef LODEPNG_COMPILE_DECODER
|
||||
/*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/
|
||||
unsigned lodepng_inflate(unsigned char** out, size_t* outsize,
|
||||
const unsigned char* in, size_t insize,
|
||||
const LodePNGDecompressSettings* settings);
|
||||
const unsigned char* in, size_t insize,
|
||||
const LodePNGDecompressSettings* settings);
|
||||
|
||||
/*
|
||||
Decompresses Zlib data. Reallocates the out buffer and appends the data. The
|
||||
@@ -751,8 +745,8 @@ Either, *out must be NULL and *outsize must be 0, or, *out must be a valid
|
||||
buffer and *outsize its size in bytes. out must be freed by user after usage.
|
||||
*/
|
||||
unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize,
|
||||
const unsigned char* in, size_t insize,
|
||||
const LodePNGDecompressSettings* settings);
|
||||
const unsigned char* in, size_t insize,
|
||||
const LodePNGDecompressSettings* settings);
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
@@ -764,20 +758,20 @@ Either, *out must be NULL and *outsize must be 0, or, *out must be a valid
|
||||
buffer and *outsize its size in bytes. out must be freed by user after usage.
|
||||
*/
|
||||
unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize,
|
||||
const unsigned char* in, size_t insize,
|
||||
const LodePNGCompressSettings* settings);
|
||||
const unsigned char* in, size_t insize,
|
||||
const LodePNGCompressSettings* settings);
|
||||
|
||||
/*
|
||||
Find length-limited Huffman code for given frequencies. This function is in the
|
||||
public interface only for tests, it's used internally by lodepng_deflate.
|
||||
*/
|
||||
unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies,
|
||||
size_t numcodes, unsigned maxbitlen);
|
||||
size_t numcodes, unsigned maxbitlen);
|
||||
|
||||
/*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/
|
||||
unsigned lodepng_deflate(unsigned char** out, size_t* outsize,
|
||||
const unsigned char* in, size_t insize,
|
||||
const LodePNGCompressSettings* settings);
|
||||
const unsigned char* in, size_t insize,
|
||||
const LodePNGCompressSettings* settings);
|
||||
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
#endif /*LODEPNG_COMPILE_ZLIB*/
|
||||
@@ -811,31 +805,31 @@ namespace lodepng
|
||||
#ifdef LODEPNG_COMPILE_PNG
|
||||
class State : public LodePNGState
|
||||
{
|
||||
public:
|
||||
State();
|
||||
State(const State& other);
|
||||
virtual ~State();
|
||||
State& operator=(const State& other);
|
||||
public:
|
||||
State();
|
||||
State(const State& other);
|
||||
virtual ~State();
|
||||
State& operator=(const State& other);
|
||||
};
|
||||
|
||||
#ifdef LODEPNG_COMPILE_DECODER
|
||||
//Same as other lodepng::decode, but using a State for more settings and information.
|
||||
unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
|
||||
State& state,
|
||||
const unsigned char* in, size_t insize);
|
||||
State& state,
|
||||
const unsigned char* in, size_t insize);
|
||||
unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
|
||||
State& state,
|
||||
const std::vector<unsigned char>& in);
|
||||
State& state,
|
||||
const std::vector<unsigned char>& in);
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
//Same as other lodepng::encode, but using a State for more settings and information.
|
||||
unsigned encode(std::vector<unsigned char>& out,
|
||||
const unsigned char* in, unsigned w, unsigned h,
|
||||
State& state);
|
||||
const unsigned char* in, unsigned w, unsigned h,
|
||||
State& state);
|
||||
unsigned encode(std::vector<unsigned char>& out,
|
||||
const std::vector<unsigned char>& in, unsigned w, unsigned h,
|
||||
State& state);
|
||||
const std::vector<unsigned char>& in, unsigned w, unsigned h,
|
||||
State& state);
|
||||
#endif /*LODEPNG_COMPILE_ENCODER*/
|
||||
|
||||
#ifdef LODEPNG_COMPILE_DISK
|
||||
@@ -850,31 +844,31 @@ Save the binary data in an std::vector to a file on disk. The file is overwritte
|
||||
without warning.
|
||||
*/
|
||||
void save_file(const std::vector<unsigned char>& buffer, const std::string& filename);
|
||||
#endif //LODEPNG_COMPILE_DISK
|
||||
#endif //LODEPNG_COMPILE_PNG
|
||||
#endif //LODEPNG_COMPILE_DISK
|
||||
#endif //LODEPNG_COMPILE_PNG
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ZLIB
|
||||
#ifdef LODEPNG_COMPILE_DECODER
|
||||
//Zlib-decompress an unsigned char buffer
|
||||
unsigned decompress(std::vector<unsigned char>& out, const unsigned char* in, size_t insize,
|
||||
const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings);
|
||||
const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings);
|
||||
|
||||
//Zlib-decompress an std::vector
|
||||
unsigned decompress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in,
|
||||
const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings);
|
||||
#endif //LODEPNG_COMPILE_DECODER
|
||||
const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings);
|
||||
#endif //LODEPNG_COMPILE_DECODER
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
//Zlib-compress an unsigned char buffer
|
||||
unsigned compress(std::vector<unsigned char>& out, const unsigned char* in, size_t insize,
|
||||
const LodePNGCompressSettings& settings = lodepng_default_compress_settings);
|
||||
const LodePNGCompressSettings& settings = lodepng_default_compress_settings);
|
||||
|
||||
//Zlib-compress an std::vector
|
||||
unsigned compress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in,
|
||||
const LodePNGCompressSettings& settings = lodepng_default_compress_settings);
|
||||
#endif //LODEPNG_COMPILE_ENCODER
|
||||
#endif //LODEPNG_COMPILE_ZLIB
|
||||
} //namespace lodepng
|
||||
const LodePNGCompressSettings& settings = lodepng_default_compress_settings);
|
||||
#endif //LODEPNG_COMPILE_ENCODER
|
||||
#endif //LODEPNG_COMPILE_ZLIB
|
||||
} //namespace lodepng
|
||||
#endif /*LODEPNG_COMPILE_CPP*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "strtools.h"
|
||||
#include "pathtools.h"
|
||||
|
||||
#if defined( _WIN32)
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#include <shobjidl.h>
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#define _S_IFDIR S_IFDIR // really from tier0/platform.h which we dont have yet
|
||||
#define _S_IFDIR S_IFDIR // really from tier0/platform.h which we dont have yet
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -32,32 +32,32 @@
|
||||
/** Returns the path (including filename) to the current executable */
|
||||
std::string Path_GetExecutablePath()
|
||||
{
|
||||
#if defined( _WIN32 )
|
||||
#if defined(_WIN32)
|
||||
wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
|
||||
char *pchPath = new char[MAX_UNICODE_PATH_IN_UTF8];
|
||||
::GetModuleFileNameW( NULL, pwchPath, MAX_UNICODE_PATH );
|
||||
WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
|
||||
::GetModuleFileNameW(NULL, pwchPath, MAX_UNICODE_PATH);
|
||||
WideCharToMultiByte(CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL);
|
||||
delete[] pwchPath;
|
||||
|
||||
std::string sPath = pchPath;
|
||||
delete[] pchPath;
|
||||
return sPath;
|
||||
#elif defined( OSX )
|
||||
#elif defined(OSX)
|
||||
char rchPath[1024];
|
||||
uint32_t nBuff = sizeof( rchPath );
|
||||
uint32_t nBuff = sizeof(rchPath);
|
||||
bool bSuccess = _NSGetExecutablePath(rchPath, &nBuff) == 0;
|
||||
rchPath[nBuff-1] = '\0';
|
||||
if( bSuccess )
|
||||
rchPath[nBuff - 1] = '\0';
|
||||
if (bSuccess)
|
||||
return rchPath;
|
||||
else
|
||||
return "";
|
||||
#elif defined LINUX
|
||||
char rchPath[1024];
|
||||
size_t nBuff = sizeof( rchPath );
|
||||
ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff-1 );
|
||||
if ( nRead != -1 )
|
||||
size_t nBuff = sizeof(rchPath);
|
||||
ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff - 1);
|
||||
if (nRead != -1)
|
||||
{
|
||||
rchPath[ nRead ] = 0;
|
||||
rchPath[nRead] = 0;
|
||||
return rchPath;
|
||||
}
|
||||
else
|
||||
@@ -65,78 +65,77 @@ std::string Path_GetExecutablePath()
|
||||
return "";
|
||||
}
|
||||
#else
|
||||
AssertMsg( false, "Implement Plat_GetExecutablePath" );
|
||||
AssertMsg(false, "Implement Plat_GetExecutablePath");
|
||||
return "";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/** Returns the path of the current working directory */
|
||||
std::string Path_GetWorkingDirectory()
|
||||
{
|
||||
std::string sPath;
|
||||
#if defined( _WIN32 )
|
||||
#if defined(_WIN32)
|
||||
wchar_t buf[MAX_UNICODE_PATH];
|
||||
sPath = UTF16to8( _wgetcwd( buf, MAX_UNICODE_PATH ) );
|
||||
sPath = UTF16to8(_wgetcwd(buf, MAX_UNICODE_PATH));
|
||||
#else
|
||||
char buf[ 1024 ];
|
||||
sPath = getcwd( buf, sizeof( buf ) );
|
||||
char buf[1024];
|
||||
sPath = getcwd(buf, sizeof(buf));
|
||||
#endif
|
||||
return sPath;
|
||||
}
|
||||
|
||||
/** Sets the path of the current working directory. Returns true if this was successful. */
|
||||
bool Path_SetWorkingDirectory( const std::string & sPath )
|
||||
bool Path_SetWorkingDirectory(const std::string &sPath)
|
||||
{
|
||||
bool bSuccess;
|
||||
#if defined( _WIN32 )
|
||||
std::wstring wsPath = UTF8to16( sPath.c_str() );
|
||||
bSuccess = 0 == _wchdir( wsPath.c_str() );
|
||||
#if defined(_WIN32)
|
||||
std::wstring wsPath = UTF8to16(sPath.c_str());
|
||||
bSuccess = 0 == _wchdir(wsPath.c_str());
|
||||
#else
|
||||
bSuccess = 0 == chdir( sPath.c_str() );
|
||||
bSuccess = 0 == chdir(sPath.c_str());
|
||||
#endif
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
/** Returns the specified path without its filename */
|
||||
std::string Path_StripFilename( const std::string & sPath, char slash )
|
||||
std::string Path_StripFilename(const std::string &sPath, char slash)
|
||||
{
|
||||
if( slash == 0 )
|
||||
if (slash == 0)
|
||||
slash = Path_GetSlash();
|
||||
|
||||
std::string::size_type n = sPath.find_last_of( slash );
|
||||
if( n == std::string::npos )
|
||||
std::string::size_type n = sPath.find_last_of(slash);
|
||||
if (n == std::string::npos)
|
||||
return sPath;
|
||||
else
|
||||
return std::string( sPath.begin(), sPath.begin() + n );
|
||||
return std::string(sPath.begin(), sPath.begin() + n);
|
||||
}
|
||||
|
||||
/** returns just the filename from the provided full or relative path. */
|
||||
std::string Path_StripDirectory( const std::string & sPath, char slash )
|
||||
std::string Path_StripDirectory(const std::string &sPath, char slash)
|
||||
{
|
||||
if( slash == 0 )
|
||||
if (slash == 0)
|
||||
slash = Path_GetSlash();
|
||||
|
||||
std::string::size_type n = sPath.find_last_of( slash );
|
||||
if( n == std::string::npos )
|
||||
std::string::size_type n = sPath.find_last_of(slash);
|
||||
if (n == std::string::npos)
|
||||
return sPath;
|
||||
else
|
||||
return std::string( sPath.begin() + n + 1, sPath.end() );
|
||||
return std::string(sPath.begin() + n + 1, sPath.end());
|
||||
}
|
||||
|
||||
/** returns just the filename with no extension of the provided filename.
|
||||
* If there is a path the path is left intact. */
|
||||
std::string Path_StripExtension( const std::string & sPath )
|
||||
std::string Path_StripExtension(const std::string &sPath)
|
||||
{
|
||||
for( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
|
||||
for (std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++)
|
||||
{
|
||||
if( *i == '.' )
|
||||
if (*i == '.')
|
||||
{
|
||||
return std::string( sPath.begin(), i.base() - 1 );
|
||||
return std::string(sPath.begin(), i.base() - 1);
|
||||
}
|
||||
|
||||
// if we find a slash there is no extension
|
||||
if( *i == '\\' || *i == '/' )
|
||||
if (*i == '\\' || *i == '/')
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -145,17 +144,17 @@ std::string Path_StripExtension( const std::string & sPath )
|
||||
}
|
||||
|
||||
/** returns just extension of the provided filename (if any). */
|
||||
std::string Path_GetExtension( const std::string & sPath )
|
||||
std::string Path_GetExtension(const std::string &sPath)
|
||||
{
|
||||
for ( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
|
||||
for (std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++)
|
||||
{
|
||||
if ( *i == '.' )
|
||||
if (*i == '.')
|
||||
{
|
||||
return std::string( i.base(), sPath.end() );
|
||||
return std::string(i.base(), sPath.end());
|
||||
}
|
||||
|
||||
// if we find a slash there is no extension
|
||||
if ( *i == '\\' || *i == '/' )
|
||||
if (*i == '\\' || *i == '/')
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -163,70 +162,67 @@ std::string Path_GetExtension( const std::string & sPath )
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Path_IsAbsolute( const std::string & sPath )
|
||||
bool Path_IsAbsolute(const std::string &sPath)
|
||||
{
|
||||
if( sPath.empty() )
|
||||
if (sPath.empty())
|
||||
return false;
|
||||
|
||||
#if defined( WIN32 )
|
||||
if ( sPath.size() < 3 ) // must be c:\x or \\x at least
|
||||
#if defined(WIN32)
|
||||
if (sPath.size() < 3) // must be c:\x or \\x at least
|
||||
return false;
|
||||
|
||||
if ( sPath[1] == ':' ) // drive letter plus slash, but must test both slash cases
|
||||
if (sPath[1] == ':') // drive letter plus slash, but must test both slash cases
|
||||
{
|
||||
if ( sPath[2] == '\\' || sPath[2] == '/' )
|
||||
if (sPath[2] == '\\' || sPath[2] == '/')
|
||||
return true;
|
||||
}
|
||||
else if ( sPath[0] == '\\' && sPath[1] == '\\' ) // UNC path
|
||||
else if (sPath[0] == '\\' && sPath[1] == '\\') // UNC path
|
||||
return true;
|
||||
#else
|
||||
if( sPath[0] == '\\' || sPath[0] == '/' ) // any leading slash
|
||||
if (sPath[0] == '\\' || sPath[0] == '/') // any leading slash
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Makes an absolute path from a relative path and a base path */
|
||||
std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash )
|
||||
std::string Path_MakeAbsolute(const std::string &sRelativePath, const std::string &sBasePath, char slash)
|
||||
{
|
||||
if( slash == 0 )
|
||||
if (slash == 0)
|
||||
slash = Path_GetSlash();
|
||||
|
||||
if( Path_IsAbsolute( sRelativePath ) )
|
||||
if (Path_IsAbsolute(sRelativePath))
|
||||
return sRelativePath;
|
||||
else
|
||||
{
|
||||
if( !Path_IsAbsolute( sBasePath ) )
|
||||
if (!Path_IsAbsolute(sBasePath))
|
||||
return "";
|
||||
|
||||
std::string sCompacted = Path_Compact( Path_Join( sBasePath, sRelativePath, slash ), slash );
|
||||
if( Path_IsAbsolute( sCompacted ) )
|
||||
std::string sCompacted = Path_Compact(Path_Join(sBasePath, sRelativePath, slash), slash);
|
||||
if (Path_IsAbsolute(sCompacted))
|
||||
return sCompacted;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Fixes the directory separators for the current platform */
|
||||
std::string Path_FixSlashes( const std::string & sPath, char slash )
|
||||
std::string Path_FixSlashes(const std::string &sPath, char slash)
|
||||
{
|
||||
if( slash == 0 )
|
||||
if (slash == 0)
|
||||
slash = Path_GetSlash();
|
||||
|
||||
std::string sFixed = sPath;
|
||||
for( std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++ )
|
||||
for (std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++)
|
||||
{
|
||||
if( *i == '/' || *i == '\\' )
|
||||
if (*i == '/' || *i == '\\')
|
||||
*i = slash;
|
||||
}
|
||||
|
||||
return sFixed;
|
||||
}
|
||||
|
||||
|
||||
char Path_GetSlash()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
@@ -237,65 +233,63 @@ char Path_GetSlash()
|
||||
}
|
||||
|
||||
/** Jams two paths together with the right kind of slash */
|
||||
std::string Path_Join( const std::string & first, const std::string & second, char slash )
|
||||
std::string Path_Join(const std::string &first, const std::string &second, char slash)
|
||||
{
|
||||
if( slash == 0 )
|
||||
if (slash == 0)
|
||||
slash = Path_GetSlash();
|
||||
|
||||
// only insert a slash if we don't already have one
|
||||
std::string::size_type nLen = first.length();
|
||||
if( !nLen )
|
||||
if (!nLen)
|
||||
return second;
|
||||
#if defined(_WIN32)
|
||||
if( first.back() == '\\' || first.back() == '/' )
|
||||
nLen--;
|
||||
if (first.back() == '\\' || first.back() == '/')
|
||||
nLen--;
|
||||
#else
|
||||
char last_char = first[first.length()-1];
|
||||
char last_char = first[first.length() - 1];
|
||||
if (last_char == '\\' || last_char == '/')
|
||||
nLen--;
|
||||
nLen--;
|
||||
#endif
|
||||
|
||||
return first.substr( 0, nLen ) + std::string( 1, slash ) + second;
|
||||
return first.substr(0, nLen) + std::string(1, slash) + second;
|
||||
}
|
||||
|
||||
|
||||
std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash )
|
||||
std::string Path_Join(const std::string &first, const std::string &second, const std::string &third, char slash)
|
||||
{
|
||||
return Path_Join( Path_Join( first, second, slash ), third, slash );
|
||||
return Path_Join(Path_Join(first, second, slash), third, slash);
|
||||
}
|
||||
|
||||
std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash )
|
||||
std::string Path_Join(const std::string &first, const std::string &second, const std::string &third, const std::string &fourth, char slash)
|
||||
{
|
||||
return Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash );
|
||||
return Path_Join(Path_Join(Path_Join(first, second, slash), third, slash), fourth, slash);
|
||||
}
|
||||
|
||||
std::string Path_Join(
|
||||
const std::string & first,
|
||||
const std::string & second,
|
||||
const std::string & third,
|
||||
const std::string & fourth,
|
||||
const std::string & fifth,
|
||||
char slash )
|
||||
std::string Path_Join(
|
||||
const std::string &first,
|
||||
const std::string &second,
|
||||
const std::string &third,
|
||||
const std::string &fourth,
|
||||
const std::string &fifth,
|
||||
char slash)
|
||||
{
|
||||
return Path_Join( Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash ), fifth, slash );
|
||||
return Path_Join(Path_Join(Path_Join(Path_Join(first, second, slash), third, slash), fourth, slash), fifth, slash);
|
||||
}
|
||||
|
||||
|
||||
std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash )
|
||||
std::string Path_RemoveTrailingSlash(const std::string &sRawPath, char slash)
|
||||
{
|
||||
if ( slash == 0 )
|
||||
if (slash == 0)
|
||||
slash = Path_GetSlash();
|
||||
|
||||
std::string sPath = sRawPath;
|
||||
std::string::size_type nCurrent = sRawPath.length();
|
||||
if ( nCurrent == 0 )
|
||||
if (nCurrent == 0)
|
||||
return sPath;
|
||||
|
||||
int nLastFound = -1;
|
||||
nCurrent--;
|
||||
while( nCurrent != 0 )
|
||||
while (nCurrent != 0)
|
||||
{
|
||||
if ( sRawPath[ nCurrent ] == slash )
|
||||
if (sRawPath[nCurrent] == slash)
|
||||
{
|
||||
nLastFound = (int)nCurrent;
|
||||
nCurrent--;
|
||||
@@ -305,32 +299,31 @@ std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nLastFound >= 0 )
|
||||
|
||||
if (nLastFound >= 0)
|
||||
{
|
||||
sPath.erase( nLastFound, std::string::npos );
|
||||
sPath.erase(nLastFound, std::string::npos);
|
||||
}
|
||||
|
||||
|
||||
return sPath;
|
||||
}
|
||||
|
||||
|
||||
/** Removes redundant <dir>/.. elements in the path. Returns an empty path if the
|
||||
* specified path has a broken number of directories for its number of ..s */
|
||||
std::string Path_Compact( const std::string & sRawPath, char slash )
|
||||
std::string Path_Compact(const std::string &sRawPath, char slash)
|
||||
{
|
||||
if( slash == 0 )
|
||||
if (slash == 0)
|
||||
slash = Path_GetSlash();
|
||||
|
||||
std::string sPath = Path_FixSlashes( sRawPath, slash );
|
||||
std::string sSlashString( 1, slash );
|
||||
std::string sPath = Path_FixSlashes(sRawPath, slash);
|
||||
std::string sSlashString(1, slash);
|
||||
|
||||
// strip out all /./
|
||||
for( std::string::size_type i = 0; (i + 3) < sPath.length(); )
|
||||
for (std::string::size_type i = 0; (i + 3) < sPath.length();)
|
||||
{
|
||||
if( sPath[ i ] == slash && sPath[ i+1 ] == '.' && sPath[ i+2 ] == slash )
|
||||
if (sPath[i] == slash && sPath[i + 1] == '.' && sPath[i + 2] == slash)
|
||||
{
|
||||
sPath.replace( i, 3, sSlashString );
|
||||
sPath.replace(i, 3, sSlashString);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -338,49 +331,44 @@ std::string Path_Compact( const std::string & sRawPath, char slash )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get rid of trailing /. but leave the path separator
|
||||
if( sPath.length() > 2 )
|
||||
if (sPath.length() > 2)
|
||||
{
|
||||
std::string::size_type len = sPath.length();
|
||||
if( sPath[ len-1 ] == '.' && sPath[ len-2 ] == slash )
|
||||
if (sPath[len - 1] == '.' && sPath[len - 2] == slash)
|
||||
{
|
||||
// sPath.pop_back();
|
||||
sPath[len-1] = 0; // for now, at least
|
||||
// sPath.pop_back();
|
||||
sPath[len - 1] = 0; // for now, at least
|
||||
}
|
||||
}
|
||||
|
||||
// get rid of leading ./
|
||||
if( sPath.length() > 2 )
|
||||
// get rid of leading ./
|
||||
if (sPath.length() > 2)
|
||||
{
|
||||
if( sPath[ 0 ] == '.' && sPath[ 1 ] == slash )
|
||||
if (sPath[0] == '.' && sPath[1] == slash)
|
||||
{
|
||||
sPath.replace( 0, 2, "" );
|
||||
sPath.replace(0, 2, "");
|
||||
}
|
||||
}
|
||||
|
||||
// each time we encounter .. back up until we've found the previous directory name
|
||||
// then get rid of both
|
||||
std::string::size_type i = 0;
|
||||
while( i < sPath.length() )
|
||||
while (i < sPath.length())
|
||||
{
|
||||
if( i > 0 && sPath.length() - i >= 2
|
||||
&& sPath[i] == '.'
|
||||
&& sPath[i+1] == '.'
|
||||
&& ( i + 2 == sPath.length() || sPath[ i+2 ] == slash )
|
||||
&& sPath[ i-1 ] == slash )
|
||||
if (i > 0 && sPath.length() - i >= 2 && sPath[i] == '.' && sPath[i + 1] == '.' && (i + 2 == sPath.length() || sPath[i + 2] == slash) && sPath[i - 1] == slash)
|
||||
{
|
||||
// check if we've hit the start of the string and have a bogus path
|
||||
if( i == 1 )
|
||||
if (i == 1)
|
||||
return "";
|
||||
|
||||
|
||||
// find the separator before i-1
|
||||
std::string::size_type iDirStart = i-2;
|
||||
while( iDirStart > 0 && sPath[ iDirStart - 1 ] != slash )
|
||||
std::string::size_type iDirStart = i - 2;
|
||||
while (iDirStart > 0 && sPath[iDirStart - 1] != slash)
|
||||
--iDirStart;
|
||||
|
||||
// remove everything from iDirStart to i+2
|
||||
sPath.replace( iDirStart, (i - iDirStart) + 3, "" );
|
||||
sPath.replace(iDirStart, (i - iDirStart) + 3, "");
|
||||
|
||||
// start over
|
||||
i = 0;
|
||||
@@ -394,7 +382,6 @@ std::string Path_Compact( const std::string & sRawPath, char slash )
|
||||
return sPath;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the path to the current DLL or exe */
|
||||
std::string Path_GetThisModulePath()
|
||||
{
|
||||
@@ -402,57 +389,55 @@ std::string Path_GetThisModulePath()
|
||||
#ifdef WIN32
|
||||
HMODULE hmodule = NULL;
|
||||
|
||||
::GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCTSTR>(Path_GetThisModulePath), &hmodule );
|
||||
::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCTSTR>(Path_GetThisModulePath), &hmodule);
|
||||
|
||||
wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
|
||||
char *pchPath = new char[ MAX_UNICODE_PATH_IN_UTF8 ];
|
||||
::GetModuleFileNameW( hmodule, pwchPath, MAX_UNICODE_PATH );
|
||||
WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
|
||||
char *pchPath = new char[MAX_UNICODE_PATH_IN_UTF8];
|
||||
::GetModuleFileNameW(hmodule, pwchPath, MAX_UNICODE_PATH);
|
||||
WideCharToMultiByte(CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL);
|
||||
delete[] pwchPath;
|
||||
|
||||
std::string sPath = pchPath;
|
||||
delete [] pchPath;
|
||||
delete[] pchPath;
|
||||
return sPath;
|
||||
|
||||
#elif defined( OSX ) || defined( LINUX )
|
||||
#elif defined(OSX) || defined(LINUX)
|
||||
// get the addr of a function in vrclient.so and then ask the dlopen system about it
|
||||
Dl_info info;
|
||||
dladdr( (void *)Path_GetThisModulePath, &info );
|
||||
dladdr((void *)Path_GetThisModulePath, &info);
|
||||
return info.dli_fname;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** returns true if the specified path exists and is a directory */
|
||||
bool Path_IsDirectory( const std::string & sPath )
|
||||
bool Path_IsDirectory(const std::string &sPath)
|
||||
{
|
||||
std::string sFixedPath = Path_FixSlashes( sPath );
|
||||
if( sFixedPath.empty() )
|
||||
std::string sFixedPath = Path_FixSlashes(sPath);
|
||||
if (sFixedPath.empty())
|
||||
return false;
|
||||
char cLast = sFixedPath[ sFixedPath.length() - 1 ];
|
||||
if( cLast == '/' || cLast == '\\' )
|
||||
sFixedPath.erase( sFixedPath.end() - 1, sFixedPath.end() );
|
||||
char cLast = sFixedPath[sFixedPath.length() - 1];
|
||||
if (cLast == '/' || cLast == '\\')
|
||||
sFixedPath.erase(sFixedPath.end() - 1, sFixedPath.end());
|
||||
|
||||
// see if the specified path actually exists.
|
||||
// see if the specified path actually exists.
|
||||
|
||||
#if defined(POSIX)
|
||||
struct stat buf;
|
||||
if ( stat( sFixedPath.c_str(), &buf ) == -1 )
|
||||
struct stat buf;
|
||||
if (stat(sFixedPath.c_str(), &buf) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined( LINUX ) || defined( OSX )
|
||||
return S_ISDIR( buf.st_mode );
|
||||
#if defined(LINUX) || defined(OSX)
|
||||
return S_ISDIR(buf.st_mode);
|
||||
#else
|
||||
return (buf.st_mode & _S_IFDIR) != 0;
|
||||
#endif
|
||||
|
||||
#else
|
||||
struct _stat buf;
|
||||
std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
|
||||
if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
|
||||
struct _stat buf;
|
||||
std::wstring wsFixedPath = UTF8to16(sFixedPath.c_str());
|
||||
if (_wstat(wsFixedPath.c_str(), &buf) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -462,12 +447,12 @@ bool Path_IsDirectory( const std::string & sPath )
|
||||
}
|
||||
|
||||
/** returns true if the specified path represents an app bundle */
|
||||
bool Path_IsAppBundle( const std::string & sPath )
|
||||
bool Path_IsAppBundle(const std::string &sPath)
|
||||
{
|
||||
#if defined(OSX)
|
||||
NSBundle *bundle = [ NSBundle bundleWithPath: [ NSString stringWithUTF8String:sPath.c_str() ] ];
|
||||
bool bisAppBundle = ( nullptr != bundle );
|
||||
[ bundle release ];
|
||||
NSBundle *bundle = [NSBundle bundleWithPath:[NSString stringWithUTF8String:sPath.c_str()]];
|
||||
bool bisAppBundle = (nullptr != bundle);
|
||||
[bundle release];
|
||||
return bisAppBundle;
|
||||
#else
|
||||
return false;
|
||||
@@ -477,22 +462,22 @@ bool Path_IsAppBundle( const std::string & sPath )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns true if the the path exists
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Path_Exists( const std::string & sPath )
|
||||
bool Path_Exists(const std::string &sPath)
|
||||
{
|
||||
std::string sFixedPath = Path_FixSlashes( sPath );
|
||||
if( sFixedPath.empty() )
|
||||
std::string sFixedPath = Path_FixSlashes(sPath);
|
||||
if (sFixedPath.empty())
|
||||
return false;
|
||||
|
||||
#if defined( WIN32 )
|
||||
struct _stat buf;
|
||||
std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
|
||||
if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
|
||||
#if defined(WIN32)
|
||||
struct _stat buf;
|
||||
std::wstring wsFixedPath = UTF8to16(sFixedPath.c_str());
|
||||
if (_wstat(wsFixedPath.c_str(), &buf) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
struct stat buf;
|
||||
if ( stat ( sFixedPath.c_str(), &buf ) == -1)
|
||||
if (stat(sFixedPath.c_str(), &buf) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -501,78 +486,75 @@ bool Path_Exists( const std::string & sPath )
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: helper to find a directory upstream from a given path
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
|
||||
std::string Path_FindParentDirectoryRecursively(const std::string &strStartDirectory, const std::string &strDirectoryName)
|
||||
{
|
||||
std::string strFoundPath = "";
|
||||
std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
|
||||
if ( strCurrentPath.length() == 0 )
|
||||
std::string strCurrentPath = Path_FixSlashes(strStartDirectory);
|
||||
if (strCurrentPath.length() == 0)
|
||||
return "";
|
||||
|
||||
bool bExists = Path_Exists( strCurrentPath );
|
||||
std::string strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
|
||||
if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
|
||||
bool bExists = Path_Exists(strCurrentPath);
|
||||
std::string strCurrentDirectoryName = Path_StripDirectory(strCurrentPath);
|
||||
if (bExists && stricmp(strCurrentDirectoryName.c_str(), strDirectoryName.c_str()) == 0)
|
||||
return strCurrentPath;
|
||||
|
||||
while( bExists && strCurrentPath.length() != 0 )
|
||||
while (bExists && strCurrentPath.length() != 0)
|
||||
{
|
||||
strCurrentPath = Path_StripFilename( strCurrentPath );
|
||||
strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
|
||||
bExists = Path_Exists( strCurrentPath );
|
||||
if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
|
||||
strCurrentPath = Path_StripFilename(strCurrentPath);
|
||||
strCurrentDirectoryName = Path_StripDirectory(strCurrentPath);
|
||||
bExists = Path_Exists(strCurrentPath);
|
||||
if (bExists && stricmp(strCurrentDirectoryName.c_str(), strDirectoryName.c_str()) == 0)
|
||||
return strCurrentPath;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: helper to find a subdirectory upstream from a given path
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
|
||||
std::string Path_FindParentSubDirectoryRecursively(const std::string &strStartDirectory, const std::string &strDirectoryName)
|
||||
{
|
||||
std::string strFoundPath = "";
|
||||
std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
|
||||
if ( strCurrentPath.length() == 0 )
|
||||
std::string strCurrentPath = Path_FixSlashes(strStartDirectory);
|
||||
if (strCurrentPath.length() == 0)
|
||||
return "";
|
||||
|
||||
bool bExists = Path_Exists( strCurrentPath );
|
||||
while( bExists && strCurrentPath.length() != 0 )
|
||||
bool bExists = Path_Exists(strCurrentPath);
|
||||
while (bExists && strCurrentPath.length() != 0)
|
||||
{
|
||||
strCurrentPath = Path_StripFilename( strCurrentPath );
|
||||
bExists = Path_Exists( strCurrentPath );
|
||||
strCurrentPath = Path_StripFilename(strCurrentPath);
|
||||
bExists = Path_Exists(strCurrentPath);
|
||||
|
||||
if( Path_Exists( Path_Join( strCurrentPath, strDirectoryName ) ) )
|
||||
if (Path_Exists(Path_Join(strCurrentPath, strDirectoryName)))
|
||||
{
|
||||
strFoundPath = Path_Join( strCurrentPath, strDirectoryName );
|
||||
strFoundPath = Path_Join(strCurrentPath, strDirectoryName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return strFoundPath;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: reading and writing files in the vortex directory
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize )
|
||||
unsigned char *Path_ReadBinaryFile(const std::string &strFilename, int *pSize)
|
||||
{
|
||||
FILE *f;
|
||||
#if defined( POSIX )
|
||||
f = fopen( strFilename.c_str(), "rb" );
|
||||
#if defined(POSIX)
|
||||
f = fopen(strFilename.c_str(), "rb");
|
||||
#else
|
||||
std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
|
||||
std::wstring wstrFilename = UTF8to16(strFilename.c_str());
|
||||
// the open operation needs to be sharable, therefore use of _wfsopen instead of _wfopen_s
|
||||
f = _wfsopen( wstrFilename.c_str(), L"rb", _SH_DENYNO );
|
||||
f = _wfsopen(wstrFilename.c_str(), L"rb", _SH_DENYNO);
|
||||
#endif
|
||||
|
||||
unsigned char* buf = NULL;
|
||||
|
||||
if ( f != NULL )
|
||||
unsigned char *buf = NULL;
|
||||
|
||||
if (f != NULL)
|
||||
{
|
||||
fseek(f, 0, SEEK_END);
|
||||
int size = ftell(f);
|
||||
@@ -596,15 +578,15 @@ unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize
|
||||
return buf;
|
||||
}
|
||||
|
||||
uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize )
|
||||
uint32_t Path_ReadBinaryFile(const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize)
|
||||
{
|
||||
FILE *f;
|
||||
#if defined( POSIX )
|
||||
f = fopen( strFilename.c_str(), "rb" );
|
||||
#if defined(POSIX)
|
||||
f = fopen(strFilename.c_str(), "rb");
|
||||
#else
|
||||
std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
|
||||
errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"rb" );
|
||||
if ( err != 0 )
|
||||
std::wstring wstrFilename = UTF8to16(strFilename.c_str());
|
||||
errno_t err = _wfopen_s(&f, wstrFilename.c_str(), L"rb");
|
||||
if (err != 0)
|
||||
{
|
||||
f = NULL;
|
||||
}
|
||||
@@ -612,25 +594,25 @@ uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pB
|
||||
|
||||
uint32_t unSizeToReturn = 0;
|
||||
|
||||
if ( f != NULL )
|
||||
if (f != NULL)
|
||||
{
|
||||
fseek( f, 0, SEEK_END );
|
||||
uint32_t size = (uint32_t)ftell( f );
|
||||
fseek( f, 0, SEEK_SET );
|
||||
fseek(f, 0, SEEK_END);
|
||||
uint32_t size = (uint32_t)ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
if ( size > unSize || !pBuffer )
|
||||
if (size > unSize || !pBuffer)
|
||||
{
|
||||
unSizeToReturn = (uint32_t)size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fread( pBuffer, size, 1, f ) == 1 )
|
||||
if (fread(pBuffer, size, 1, f) == 1)
|
||||
{
|
||||
unSizeToReturn = (uint32_t)size;
|
||||
}
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return unSizeToReturn;
|
||||
@@ -639,11 +621,11 @@ uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pB
|
||||
bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, unsigned nSize)
|
||||
{
|
||||
FILE *f;
|
||||
#if defined( POSIX )
|
||||
#if defined(POSIX)
|
||||
f = fopen(strFilename.c_str(), "wb");
|
||||
#else
|
||||
std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
|
||||
errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"wb" );
|
||||
std::wstring wstrFilename = UTF8to16(strFilename.c_str());
|
||||
errno_t err = _wfopen_s(&f, wstrFilename.c_str(), L"wb");
|
||||
if (err != 0)
|
||||
{
|
||||
f = NULL;
|
||||
@@ -651,7 +633,8 @@ bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData,
|
||||
#endif
|
||||
|
||||
size_t written = 0;
|
||||
if (f != NULL) {
|
||||
if (f != NULL)
|
||||
{
|
||||
written = fwrite(pData, sizeof(unsigned char), nSize, f);
|
||||
fclose(f);
|
||||
}
|
||||
@@ -659,24 +642,24 @@ bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData,
|
||||
return written = nSize ? true : false;
|
||||
}
|
||||
|
||||
std::string Path_ReadTextFile( const std::string &strFilename )
|
||||
std::string Path_ReadTextFile(const std::string &strFilename)
|
||||
{
|
||||
// doing it this way seems backwards, but I don't
|
||||
// see an easy way to do this with C/C++ style IO
|
||||
// that isn't worse...
|
||||
int size;
|
||||
unsigned char* buf = Path_ReadBinaryFile( strFilename, &size );
|
||||
unsigned char *buf = Path_ReadBinaryFile(strFilename, &size);
|
||||
if (!buf)
|
||||
return "";
|
||||
|
||||
// convert CRLF -> LF
|
||||
size_t outsize = 1;
|
||||
for (int i=1; i < size; i++)
|
||||
for (int i = 1; i < size; i++)
|
||||
{
|
||||
if (buf[i] == '\n' && buf[i-1] == '\r') // CRLF
|
||||
buf[outsize-1] = '\n'; // ->LF
|
||||
if (buf[i] == '\n' && buf[i - 1] == '\r') // CRLF
|
||||
buf[outsize - 1] = '\n'; // ->LF
|
||||
else
|
||||
buf[outsize++] = buf[i]; // just copy
|
||||
buf[outsize++] = buf[i]; // just copy
|
||||
}
|
||||
|
||||
std::string ret((char *)buf, outsize);
|
||||
@@ -684,51 +667,50 @@ std::string Path_ReadTextFile( const std::string &strFilename )
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData )
|
||||
bool Path_WriteStringToTextFile(const std::string &strFilename, const char *pchData)
|
||||
{
|
||||
FILE *f;
|
||||
#if defined( POSIX )
|
||||
f = fopen( strFilename.c_str(), "w" );
|
||||
#if defined(POSIX)
|
||||
f = fopen(strFilename.c_str(), "w");
|
||||
#else
|
||||
std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
|
||||
errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"w" );
|
||||
if ( err != 0 )
|
||||
std::wstring wstrFilename = UTF8to16(strFilename.c_str());
|
||||
errno_t err = _wfopen_s(&f, wstrFilename.c_str(), L"w");
|
||||
if (err != 0)
|
||||
{
|
||||
f = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if ( f != NULL )
|
||||
if (f != NULL)
|
||||
{
|
||||
ok = fputs( pchData, f) >= 0;
|
||||
ok = fputs(pchData, f) >= 0;
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData )
|
||||
bool Path_WriteStringToTextFileAtomic(const std::string &strFilename, const char *pchData)
|
||||
{
|
||||
std::string strTmpFilename = strFilename + ".tmp";
|
||||
|
||||
if ( !Path_WriteStringToTextFile( strTmpFilename, pchData ) )
|
||||
if (!Path_WriteStringToTextFile(strTmpFilename, pchData))
|
||||
return false;
|
||||
|
||||
// Platform specific atomic file replacement
|
||||
#if defined( _WIN32 )
|
||||
std::wstring wsFilename = UTF8to16( strFilename.c_str() );
|
||||
std::wstring wsTmpFilename = UTF8to16( strTmpFilename.c_str() );
|
||||
if ( !::ReplaceFileW( wsFilename.c_str(), wsTmpFilename.c_str(), nullptr, 0, 0, 0 ) )
|
||||
// Platform specific atomic file replacement
|
||||
#if defined(_WIN32)
|
||||
std::wstring wsFilename = UTF8to16(strFilename.c_str());
|
||||
std::wstring wsTmpFilename = UTF8to16(strTmpFilename.c_str());
|
||||
if (!::ReplaceFileW(wsFilename.c_str(), wsTmpFilename.c_str(), nullptr, 0, 0, 0))
|
||||
{
|
||||
// if we couldn't ReplaceFile, try a non-atomic write as a fallback
|
||||
if ( !Path_WriteStringToTextFile( strFilename, pchData ) )
|
||||
if (!Path_WriteStringToTextFile(strFilename, pchData))
|
||||
return false;
|
||||
}
|
||||
#elif defined( POSIX )
|
||||
if ( rename( strTmpFilename.c_str(), strFilename.c_str() ) == -1 )
|
||||
#elif defined(POSIX)
|
||||
if (rename(strTmpFilename.c_str(), strFilename.c_str()) == -1)
|
||||
return false;
|
||||
#else
|
||||
#error Do not know how to write atomic file
|
||||
@@ -737,7 +719,6 @@ bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const cha
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
#define FILE_URL_PREFIX "file:///"
|
||||
#else
|
||||
@@ -747,31 +728,29 @@ bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const cha
|
||||
// ----------------------------------------------------------------------------------------------------------------------------
|
||||
// Purpose: Turns a path to a file on disk into a URL (or just returns the value if it's already a URL)
|
||||
// ----------------------------------------------------------------------------------------------------------------------------
|
||||
std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath )
|
||||
std::string Path_FilePathToUrl(const std::string &sRelativePath, const std::string &sBasePath)
|
||||
{
|
||||
if ( !strnicmp( sRelativePath.c_str(), "http://", 7 )
|
||||
|| !strnicmp( sRelativePath.c_str(), "https://", 8 )
|
||||
|| !strnicmp( sRelativePath.c_str(), "file://", 7 ) )
|
||||
if (!strnicmp(sRelativePath.c_str(), "http://", 7) || !strnicmp(sRelativePath.c_str(), "https://", 8) || !strnicmp(sRelativePath.c_str(), "file://", 7))
|
||||
{
|
||||
return sRelativePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string sAbsolute = Path_MakeAbsolute( sRelativePath, sBasePath );
|
||||
if ( sAbsolute.empty() )
|
||||
std::string sAbsolute = Path_MakeAbsolute(sRelativePath, sBasePath);
|
||||
if (sAbsolute.empty())
|
||||
return sAbsolute;
|
||||
return std::string( FILE_URL_PREFIX ) + sAbsolute;
|
||||
return std::string(FILE_URL_PREFIX) + sAbsolute;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// Purpose: Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
std::string Path_UrlToFilePath( const std::string & sFileUrl )
|
||||
std::string Path_UrlToFilePath(const std::string &sFileUrl)
|
||||
{
|
||||
if ( !strnicmp( sFileUrl.c_str(), FILE_URL_PREFIX, strlen( FILE_URL_PREFIX ) ) )
|
||||
if (!strnicmp(sFileUrl.c_str(), FILE_URL_PREFIX, strlen(FILE_URL_PREFIX)))
|
||||
{
|
||||
return sFileUrl.c_str() + strlen( FILE_URL_PREFIX );
|
||||
return sFileUrl.c_str() + strlen(FILE_URL_PREFIX);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -779,42 +758,41 @@ std::string Path_UrlToFilePath( const std::string & sFileUrl )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// Purpose: Returns the root of the directory the system wants us to store user documents in
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
std::string GetUserDocumentsPath()
|
||||
{
|
||||
#if defined( WIN32 )
|
||||
#if defined(WIN32)
|
||||
WCHAR rwchPath[MAX_PATH];
|
||||
|
||||
if ( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) )
|
||||
if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath)))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Convert the path to UTF-8 and store in the output
|
||||
std::string sUserPath = UTF16to8( rwchPath );
|
||||
std::string sUserPath = UTF16to8(rwchPath);
|
||||
|
||||
return sUserPath;
|
||||
#elif defined( OSX )
|
||||
@autoreleasepool {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
|
||||
if ( [paths count] == 0 )
|
||||
#elif defined(OSX)
|
||||
@autoreleasepool
|
||||
{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count] == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
return [[paths objectAtIndex:0] UTF8String];
|
||||
}
|
||||
#elif defined( LINUX )
|
||||
#elif defined(LINUX)
|
||||
// @todo: not solved/changed as part of OSX - still not real - just removed old class based steam cut and paste
|
||||
const char *pchHome = getenv( "HOME" );
|
||||
if ( pchHome == NULL )
|
||||
const char *pchHome = getenv("HOME");
|
||||
if (pchHome == NULL)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return pchHome;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ std::string Path_GetExecutablePath();
|
||||
std::string Path_GetWorkingDirectory();
|
||||
|
||||
/** Sets the path of the current working directory. Returns true if this was successful. */
|
||||
bool Path_SetWorkingDirectory( const std::string & sPath );
|
||||
bool Path_SetWorkingDirectory(const std::string &sPath);
|
||||
|
||||
/** returns the path (including filename) of the current shared lib or DLL */
|
||||
std::string Path_GetThisModulePath();
|
||||
@@ -19,111 +19,110 @@ std::string Path_GetThisModulePath();
|
||||
/** Returns the specified path without its filename.
|
||||
* If slash is unspecified the native path separator of the current platform
|
||||
* will be used. */
|
||||
std::string Path_StripFilename( const std::string & sPath, char slash = 0 );
|
||||
std::string Path_StripFilename(const std::string &sPath, char slash = 0);
|
||||
|
||||
/** returns just the filename from the provided full or relative path. */
|
||||
std::string Path_StripDirectory( const std::string & sPath, char slash = 0 );
|
||||
std::string Path_StripDirectory(const std::string &sPath, char slash = 0);
|
||||
|
||||
/** returns just the filename with no extension of the provided filename.
|
||||
* If there is a path the path is left intact. */
|
||||
std::string Path_StripExtension( const std::string & sPath );
|
||||
std::string Path_StripExtension(const std::string &sPath);
|
||||
|
||||
/** returns just extension of the provided filename (if any). */
|
||||
std::string Path_GetExtension( const std::string & sPath );
|
||||
std::string Path_GetExtension(const std::string &sPath);
|
||||
|
||||
/** Returns true if the path is absolute */
|
||||
bool Path_IsAbsolute( const std::string & sPath );
|
||||
bool Path_IsAbsolute(const std::string &sPath);
|
||||
|
||||
/** Makes an absolute path from a relative path and a base path */
|
||||
std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash = 0 );
|
||||
std::string Path_MakeAbsolute(const std::string &sRelativePath, const std::string &sBasePath, char slash = 0);
|
||||
|
||||
/** Fixes the directory separators for the current platform.
|
||||
* If slash is unspecified the native path separator of the current platform
|
||||
* will be used. */
|
||||
std::string Path_FixSlashes( const std::string & sPath, char slash = 0 );
|
||||
std::string Path_FixSlashes(const std::string &sPath, char slash = 0);
|
||||
|
||||
/** Returns the path separator for the current platform */
|
||||
char Path_GetSlash();
|
||||
|
||||
/** Jams two paths together with the right kind of slash */
|
||||
std::string Path_Join( const std::string & first, const std::string & second, char slash = 0 );
|
||||
std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash = 0 );
|
||||
std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash = 0 );
|
||||
std::string Path_Join(
|
||||
const std::string & first,
|
||||
const std::string & second,
|
||||
const std::string & third,
|
||||
const std::string & fourth,
|
||||
const std::string & fifth,
|
||||
char slash = 0 );
|
||||
|
||||
std::string Path_Join(const std::string &first, const std::string &second, char slash = 0);
|
||||
std::string Path_Join(const std::string &first, const std::string &second, const std::string &third, char slash = 0);
|
||||
std::string Path_Join(const std::string &first, const std::string &second, const std::string &third, const std::string &fourth, char slash = 0);
|
||||
std::string Path_Join(
|
||||
const std::string &first,
|
||||
const std::string &second,
|
||||
const std::string &third,
|
||||
const std::string &fourth,
|
||||
const std::string &fifth,
|
||||
char slash = 0);
|
||||
|
||||
/** Removes redundant <dir>/.. elements in the path. Returns an empty path if the
|
||||
* specified path has a broken number of directories for its number of ..s.
|
||||
* If slash is unspecified the native path separator of the current platform
|
||||
* will be used. */
|
||||
std::string Path_Compact( const std::string & sRawPath, char slash = 0 );
|
||||
std::string Path_Compact(const std::string &sRawPath, char slash = 0);
|
||||
|
||||
//** Removed trailing slashes */
|
||||
std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash = 0 );
|
||||
std::string Path_RemoveTrailingSlash(const std::string &sRawPath, char slash = 0);
|
||||
|
||||
/** returns true if the specified path exists and is a directory */
|
||||
bool Path_IsDirectory( const std::string & sPath );
|
||||
bool Path_IsDirectory(const std::string &sPath);
|
||||
|
||||
/** returns true if the specified path represents an app bundle */
|
||||
bool Path_IsAppBundle( const std::string & sPath );
|
||||
bool Path_IsAppBundle(const std::string &sPath);
|
||||
|
||||
/** returns true if the the path exists */
|
||||
bool Path_Exists( const std::string & sPath );
|
||||
bool Path_Exists(const std::string &sPath);
|
||||
|
||||
/** Helper functions to find parent directories or subdirectories of parent directories */
|
||||
std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName );
|
||||
std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName );
|
||||
std::string Path_FindParentDirectoryRecursively(const std::string &strStartDirectory, const std::string &strDirectoryName);
|
||||
std::string Path_FindParentSubDirectoryRecursively(const std::string &strStartDirectory, const std::string &strDirectoryName);
|
||||
|
||||
/** Path operations to read or write text/binary files */
|
||||
unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize );
|
||||
uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize );
|
||||
bool Path_WriteBinaryFile( const std::string &strFilename, unsigned char *pData, unsigned nSize );
|
||||
std::string Path_ReadTextFile( const std::string &strFilename );
|
||||
bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData );
|
||||
bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData );
|
||||
unsigned char *Path_ReadBinaryFile(const std::string &strFilename, int *pSize);
|
||||
uint32_t Path_ReadBinaryFile(const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize);
|
||||
bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, unsigned nSize);
|
||||
std::string Path_ReadTextFile(const std::string &strFilename);
|
||||
bool Path_WriteStringToTextFile(const std::string &strFilename, const char *pchData);
|
||||
bool Path_WriteStringToTextFileAtomic(const std::string &strFilename, const char *pchData);
|
||||
|
||||
/** Returns a file:// url for paths, or an http or https url if that's what was provided */
|
||||
std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath );
|
||||
std::string Path_FilePathToUrl(const std::string &sRelativePath, const std::string &sBasePath);
|
||||
|
||||
/** Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned */
|
||||
std::string Path_UrlToFilePath( const std::string & sFileUrl );
|
||||
std::string Path_UrlToFilePath(const std::string &sFileUrl);
|
||||
|
||||
/** Returns the root of the directory the system wants us to store user documents in */
|
||||
std::string GetUserDocumentsPath();
|
||||
|
||||
#ifndef MAX_UNICODE_PATH
|
||||
#define MAX_UNICODE_PATH 32767
|
||||
#define MAX_UNICODE_PATH 32767
|
||||
#endif
|
||||
|
||||
#ifndef MAX_UNICODE_PATH_IN_UTF8
|
||||
#define MAX_UNICODE_PATH_IN_UTF8 (MAX_UNICODE_PATH * 4)
|
||||
#define MAX_UNICODE_PATH_IN_UTF8 (MAX_UNICODE_PATH * 4)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(WIN32)
|
||||
#define DYNAMIC_LIB_EXT ".dll"
|
||||
#define DYNAMIC_LIB_EXT ".dll"
|
||||
#ifdef _WIN64
|
||||
#define PLATSUBDIR "win64"
|
||||
#define PLATSUBDIR "win64"
|
||||
#else
|
||||
#define PLATSUBDIR "win32"
|
||||
#define PLATSUBDIR "win32"
|
||||
#endif
|
||||
#elif defined(OSX)
|
||||
#define DYNAMIC_LIB_EXT ".dylib"
|
||||
#define PLATSUBDIR "osx32"
|
||||
#define DYNAMIC_LIB_EXT ".dylib"
|
||||
#define PLATSUBDIR "osx32"
|
||||
#elif defined(LINUX)
|
||||
#define DYNAMIC_LIB_EXT ".so"
|
||||
#if defined( LINUX32 )
|
||||
#define PLATSUBDIR "linux32"
|
||||
#define DYNAMIC_LIB_EXT ".so"
|
||||
#if defined(LINUX32)
|
||||
#define PLATSUBDIR "linux32"
|
||||
#else
|
||||
#define PLATSUBDIR "linux64"
|
||||
#define PLATSUBDIR "linux64"
|
||||
#endif
|
||||
#else
|
||||
#warning "Unknown platform for PLATSUBDIR"
|
||||
#define PLATSUBDIR "unknown_platform"
|
||||
#define PLATSUBDIR "unknown_platform"
|
||||
#endif
|
||||
|
||||
@@ -9,55 +9,53 @@
|
||||
#define strnicmp strncasecmp
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool StringHasPrefix( const std::string & sString, const std::string & sPrefix )
|
||||
bool StringHasPrefix(const std::string &sString, const std::string &sPrefix)
|
||||
{
|
||||
return 0 == strnicmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() );
|
||||
return 0 == strnicmp(sString.c_str(), sPrefix.c_str(), sPrefix.length());
|
||||
}
|
||||
|
||||
bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix )
|
||||
bool StringHasPrefixCaseSensitive(const std::string &sString, const std::string &sPrefix)
|
||||
{
|
||||
return 0 == strncmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() );
|
||||
return 0 == strncmp(sString.c_str(), sPrefix.c_str(), sPrefix.length());
|
||||
}
|
||||
|
||||
|
||||
bool StringHasSuffix( const std::string &sString, const std::string &sSuffix )
|
||||
bool StringHasSuffix(const std::string &sString, const std::string &sSuffix)
|
||||
{
|
||||
size_t cStrLen = sString.length();
|
||||
size_t cSuffixLen = sSuffix.length();
|
||||
|
||||
if ( cSuffixLen > cStrLen )
|
||||
if (cSuffixLen > cStrLen)
|
||||
return false;
|
||||
|
||||
std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen );
|
||||
std::string sStringSuffix = sString.substr(cStrLen - cSuffixLen, cSuffixLen);
|
||||
|
||||
return 0 == stricmp( sStringSuffix.c_str(), sSuffix.c_str() );
|
||||
return 0 == stricmp(sStringSuffix.c_str(), sSuffix.c_str());
|
||||
}
|
||||
|
||||
bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix )
|
||||
bool StringHasSuffixCaseSensitive(const std::string &sString, const std::string &sSuffix)
|
||||
{
|
||||
size_t cStrLen = sString.length();
|
||||
size_t cSuffixLen = sSuffix.length();
|
||||
|
||||
if ( cSuffixLen > cStrLen )
|
||||
if (cSuffixLen > cStrLen)
|
||||
return false;
|
||||
|
||||
std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen );
|
||||
std::string sStringSuffix = sString.substr(cStrLen - cSuffixLen, cSuffixLen);
|
||||
|
||||
return 0 == strncmp( sStringSuffix.c_str(), sSuffix.c_str(),cSuffixLen );
|
||||
return 0 == strncmp(sStringSuffix.c_str(), sSuffix.c_str(), cSuffixLen);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string UTF16to8(const wchar_t * in)
|
||||
std::string UTF16to8(const wchar_t *in)
|
||||
{
|
||||
std::string out;
|
||||
unsigned int codepoint = 0;
|
||||
for ( ; in && *in != 0; ++in )
|
||||
for (; in && *in != 0; ++in)
|
||||
{
|
||||
if (*in >= 0xd800 && *in <= 0xdbff)
|
||||
codepoint = ((*in - 0xd800) << 10) + 0x10000;
|
||||
@@ -94,12 +92,12 @@ std::string UTF16to8(const wchar_t * in)
|
||||
return out;
|
||||
}
|
||||
|
||||
std::wstring UTF8to16(const char * in)
|
||||
std::wstring UTF8to16(const char *in)
|
||||
{
|
||||
std::wstring out;
|
||||
unsigned int codepoint = 0;
|
||||
int following = 0;
|
||||
for ( ; in && *in != 0; ++in )
|
||||
for (; in && *in != 0; ++in)
|
||||
{
|
||||
unsigned char ch = *in;
|
||||
if (ch <= 0x7f)
|
||||
@@ -145,111 +143,106 @@ std::wstring UTF8to16(const char * in)
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource )
|
||||
void strcpy_safe(char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource)
|
||||
{
|
||||
pchBuffer[ unBufferSizeBytes - 1 ] = '\0';
|
||||
strncpy( pchBuffer, pchSource, unBufferSizeBytes - 1 );
|
||||
pchBuffer[unBufferSizeBytes - 1] = '\0';
|
||||
strncpy(pchBuffer, pchSource, unBufferSizeBytes - 1);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Purpose: converts a string to upper case
|
||||
// --------------------------------------------------------------------
|
||||
std::string StringToUpper( const std::string & sString )
|
||||
std::string StringToUpper(const std::string &sString)
|
||||
{
|
||||
std::string sOut;
|
||||
sOut.reserve( sString.size() + 1 );
|
||||
for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ )
|
||||
sOut.reserve(sString.size() + 1);
|
||||
for (std::string::const_iterator i = sString.begin(); i != sString.end(); i++)
|
||||
{
|
||||
sOut.push_back( (char)toupper( *i ) );
|
||||
sOut.push_back((char)toupper(*i));
|
||||
}
|
||||
|
||||
return sOut;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Purpose: converts a string to lower case
|
||||
// --------------------------------------------------------------------
|
||||
std::string StringToLower( const std::string & sString )
|
||||
std::string StringToLower(const std::string &sString)
|
||||
{
|
||||
std::string sOut;
|
||||
sOut.reserve( sString.size() + 1 );
|
||||
for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ )
|
||||
sOut.reserve(sString.size() + 1);
|
||||
for (std::string::const_iterator i = sString.begin(); i != sString.end(); i++)
|
||||
{
|
||||
sOut.push_back( (char)tolower( *i ) );
|
||||
sOut.push_back((char)tolower(*i));
|
||||
}
|
||||
|
||||
return sOut;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen )
|
||||
uint32_t ReturnStdString(const std::string &sValue, char *pchBuffer, uint32_t unBufferLen)
|
||||
{
|
||||
uint32_t unLen = (uint32_t)sValue.length() + 1;
|
||||
if( !pchBuffer || !unBufferLen )
|
||||
if (!pchBuffer || !unBufferLen)
|
||||
return unLen;
|
||||
|
||||
if( unBufferLen < unLen )
|
||||
if (unBufferLen < unLen)
|
||||
{
|
||||
pchBuffer[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( pchBuffer, sValue.c_str(), unLen );
|
||||
memcpy(pchBuffer, sValue.c_str(), unLen);
|
||||
}
|
||||
|
||||
return unLen;
|
||||
}
|
||||
|
||||
void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen )
|
||||
void BufferToStdString(std::string &sDest, const char *pchBuffer, uint32_t unBufferLen)
|
||||
{
|
||||
sDest.resize( unBufferLen + 1 );
|
||||
memcpy( const_cast< char* >( sDest.c_str() ), pchBuffer, unBufferLen );
|
||||
const_cast< char* >( sDest.c_str() )[ unBufferLen ] = '\0';
|
||||
sDest.resize(unBufferLen + 1);
|
||||
memcpy(const_cast<char *>(sDest.c_str()), pchBuffer, unBufferLen);
|
||||
const_cast<char *>(sDest.c_str())[unBufferLen] = '\0';
|
||||
}
|
||||
|
||||
/** Returns a std::string from a uint64_t */
|
||||
std::string Uint64ToString( uint64_t ulValue )
|
||||
std::string Uint64ToString(uint64_t ulValue)
|
||||
{
|
||||
char buf[ 22 ];
|
||||
#if defined( _WIN32 )
|
||||
sprintf_s( buf, "%llu", ulValue );
|
||||
char buf[22];
|
||||
#if defined(_WIN32)
|
||||
sprintf_s(buf, "%llu", ulValue);
|
||||
#else
|
||||
snprintf( buf, sizeof( buf ), "%llu", (long long unsigned int ) ulValue );
|
||||
snprintf(buf, sizeof(buf), "%llu", (long long unsigned int)ulValue);
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/** returns a uint64_t from a string */
|
||||
uint64_t StringToUint64( const std::string & sValue )
|
||||
uint64_t StringToUint64(const std::string &sValue)
|
||||
{
|
||||
return strtoull( sValue.c_str(), NULL, 0 );
|
||||
return strtoull(sValue.c_str(), NULL, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper for converting a numeric value to a hex digit, value should be 0-15.
|
||||
//-----------------------------------------------------------------------------
|
||||
char cIntToHexDigit( int nValue )
|
||||
char cIntToHexDigit(int nValue)
|
||||
{
|
||||
//Assert( nValue >= 0 && nValue <= 15 );
|
||||
return "0123456789ABCDEF"[ nValue & 15 ];
|
||||
return "0123456789ABCDEF"[nValue & 15];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper for converting a hex char value to numeric, return -1 if the char
|
||||
// is not a valid hex digit.
|
||||
//-----------------------------------------------------------------------------
|
||||
int iHexCharToInt( char cValue )
|
||||
int iHexCharToInt(char cValue)
|
||||
{
|
||||
int32_t iValue = cValue;
|
||||
if ( (uint32_t)( iValue - '0' ) < 10 )
|
||||
if ((uint32_t)(iValue - '0') < 10)
|
||||
return iValue - '0';
|
||||
|
||||
iValue |= 0x20;
|
||||
if ( (uint32_t)( iValue - 'a' ) < 6 )
|
||||
if ((uint32_t)(iValue - 'a') < 6)
|
||||
return iValue - 'a' + 10;
|
||||
|
||||
return -1;
|
||||
@@ -259,29 +252,27 @@ int iHexCharToInt( char cValue )
|
||||
// Purpose: Internal implementation of encode, works in the strict RFC manner, or
|
||||
// with spaces turned to + like HTML form encoding.
|
||||
//-----------------------------------------------------------------------------
|
||||
void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, bool bUsePlusForSpace )
|
||||
void V_URLEncodeInternal(char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, bool bUsePlusForSpace)
|
||||
{
|
||||
//AssertMsg( nDestLen > 3*nSourceLen, "Target buffer for V_URLEncode should be 3x source length, plus one for terminating null\n" );
|
||||
|
||||
|
||||
int iDestPos = 0;
|
||||
for ( int i=0; i < nSourceLen; ++i )
|
||||
for (int i = 0; i < nSourceLen; ++i)
|
||||
{
|
||||
// worst case we need 3 additional chars
|
||||
if( (iDestPos+3) > nDestLen )
|
||||
if ((iDestPos + 3) > nDestLen)
|
||||
{
|
||||
pchDest[0] = '\0';
|
||||
// AssertMsg( false, "Target buffer too short\n" );
|
||||
// AssertMsg( false, "Target buffer too short\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// We allow only a-z, A-Z, 0-9, period, underscore, and hyphen to pass through unescaped.
|
||||
// These are the characters allowed by both the original RFC 1738 and the latest RFC 3986.
|
||||
// Current specs also allow '~', but that is forbidden under original RFC 1738.
|
||||
if ( !( pchSource[i] >= 'a' && pchSource[i] <= 'z' ) && !( pchSource[i] >= 'A' && pchSource[i] <= 'Z' ) && !(pchSource[i] >= '0' && pchSource[i] <= '9' )
|
||||
&& pchSource[i] != '-' && pchSource[i] != '_' && pchSource[i] != '.'
|
||||
)
|
||||
if (!(pchSource[i] >= 'a' && pchSource[i] <= 'z') && !(pchSource[i] >= 'A' && pchSource[i] <= 'Z') && !(pchSource[i] >= '0' && pchSource[i] <= '9') && pchSource[i] != '-' && pchSource[i] != '_' && pchSource[i] != '.')
|
||||
{
|
||||
if ( bUsePlusForSpace && pchSource[i] == ' ' )
|
||||
if (bUsePlusForSpace && pchSource[i] == ' ')
|
||||
{
|
||||
pchDest[iDestPos++] = '+';
|
||||
}
|
||||
@@ -289,16 +280,16 @@ void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, in
|
||||
{
|
||||
pchDest[iDestPos++] = '%';
|
||||
uint8_t iValue = pchSource[i];
|
||||
if ( iValue == 0 )
|
||||
if (iValue == 0)
|
||||
{
|
||||
pchDest[iDestPos++] = '0';
|
||||
pchDest[iDestPos++] = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
char cHexDigit1 = cIntToHexDigit( iValue % 16 );
|
||||
char cHexDigit1 = cIntToHexDigit(iValue % 16);
|
||||
iValue /= 16;
|
||||
char cHexDigit2 = cIntToHexDigit( iValue );
|
||||
char cHexDigit2 = cIntToHexDigit(iValue);
|
||||
pchDest[iDestPos++] = cHexDigit2;
|
||||
pchDest[iDestPos++] = cHexDigit1;
|
||||
}
|
||||
@@ -310,7 +301,7 @@ void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, in
|
||||
}
|
||||
}
|
||||
|
||||
if( (iDestPos+1) > nDestLen )
|
||||
if ((iDestPos + 1) > nDestLen)
|
||||
{
|
||||
pchDest[0] = '\0';
|
||||
//AssertMsg( false, "Target buffer too short to terminate\n" );
|
||||
@@ -321,61 +312,60 @@ void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, in
|
||||
pchDest[iDestPos++] = 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Internal implementation of decode, works in the strict RFC manner, or
|
||||
// with spaces turned to + like HTML form encoding.
|
||||
//
|
||||
// Returns the amount of space used in the output buffer.
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen, bool bUsePlusForSpace )
|
||||
size_t V_URLDecodeInternal(char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen, bool bUsePlusForSpace)
|
||||
{
|
||||
if ( nDecodeDestLen < nEncodedSourceLen )
|
||||
if (nDecodeDestLen < nEncodedSourceLen)
|
||||
{
|
||||
//AssertMsg( false, "V_URLDecode needs a dest buffer at least as large as the source" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iDestPos = 0;
|
||||
for( int i=0; i < nEncodedSourceLen; ++i )
|
||||
for (int i = 0; i < nEncodedSourceLen; ++i)
|
||||
{
|
||||
if ( bUsePlusForSpace && pchEncodedSource[i] == '+' )
|
||||
if (bUsePlusForSpace && pchEncodedSource[i] == '+')
|
||||
{
|
||||
pchDecodeDest[ iDestPos++ ] = ' ';
|
||||
pchDecodeDest[iDestPos++] = ' ';
|
||||
}
|
||||
else if ( pchEncodedSource[i] == '%' )
|
||||
else if (pchEncodedSource[i] == '%')
|
||||
{
|
||||
// Percent signifies an encoded value, look ahead for the hex code, convert to numeric, and use that
|
||||
|
||||
// First make sure we have 2 more chars
|
||||
if ( i < nEncodedSourceLen - 2 )
|
||||
if (i < nEncodedSourceLen - 2)
|
||||
{
|
||||
char cHexDigit1 = pchEncodedSource[i+1];
|
||||
char cHexDigit2 = pchEncodedSource[i+2];
|
||||
char cHexDigit1 = pchEncodedSource[i + 1];
|
||||
char cHexDigit2 = pchEncodedSource[i + 2];
|
||||
|
||||
// Turn the chars into a hex value, if they are not valid, then we'll
|
||||
// just place the % and the following two chars direct into the string,
|
||||
// even though this really shouldn't happen, who knows what bad clients
|
||||
// may do with encoding.
|
||||
bool bValid = false;
|
||||
int iValue = iHexCharToInt( cHexDigit1 );
|
||||
if ( iValue != -1 )
|
||||
int iValue = iHexCharToInt(cHexDigit1);
|
||||
if (iValue != -1)
|
||||
{
|
||||
iValue *= 16;
|
||||
int iValue2 = iHexCharToInt( cHexDigit2 );
|
||||
if ( iValue2 != -1 )
|
||||
int iValue2 = iHexCharToInt(cHexDigit2);
|
||||
if (iValue2 != -1)
|
||||
{
|
||||
iValue += iValue2;
|
||||
pchDecodeDest[ iDestPos++ ] = (char)iValue;
|
||||
pchDecodeDest[iDestPos++] = (char)iValue;
|
||||
bValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bValid )
|
||||
if (!bValid)
|
||||
{
|
||||
pchDecodeDest[ iDestPos++ ] = '%';
|
||||
pchDecodeDest[ iDestPos++ ] = cHexDigit1;
|
||||
pchDecodeDest[ iDestPos++ ] = cHexDigit2;
|
||||
pchDecodeDest[iDestPos++] = '%';
|
||||
pchDecodeDest[iDestPos++] = cHexDigit1;
|
||||
pchDecodeDest[iDestPos++] = cHexDigit2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,13 +374,13 @@ size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char
|
||||
}
|
||||
else
|
||||
{
|
||||
pchDecodeDest[ iDestPos++ ] = pchEncodedSource[i];
|
||||
pchDecodeDest[iDestPos++] = pchEncodedSource[i];
|
||||
}
|
||||
}
|
||||
|
||||
// We may not have extra room to NULL terminate, since this can be used on raw data, but if we do
|
||||
// go ahead and do it as this can avoid bugs.
|
||||
if ( iDestPos < nDecodeDestLen )
|
||||
if (iDestPos < nDecodeDestLen)
|
||||
{
|
||||
pchDecodeDest[iDestPos] = 0;
|
||||
}
|
||||
@@ -399,45 +389,43 @@ size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
|
||||
// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
|
||||
// This version of the call isn't a strict RFC implementation, but uses + for space as is
|
||||
// the standard in HTML form encoding, despite it not being part of the RFC.
|
||||
//
|
||||
// Dest buffer should be at least as large as source buffer to guarantee room for decode.
|
||||
//-----------------------------------------------------------------------------
|
||||
void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen )
|
||||
void V_URLEncode(char *pchDest, int nDestLen, const char *pchSource, int nSourceLen)
|
||||
{
|
||||
return V_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, true );
|
||||
return V_URLEncodeInternal(pchDest, nDestLen, pchSource, nSourceLen, true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
|
||||
// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
|
||||
// This version of the call isn't a strict RFC implementation, but uses + for space as is
|
||||
// the standard in HTML form encoding, despite it not being part of the RFC.
|
||||
//
|
||||
// Dest buffer should be at least as large as source buffer to guarantee room for decode.
|
||||
// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen )
|
||||
size_t V_URLDecode(char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen)
|
||||
{
|
||||
return V_URLDecodeInternal( pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, true );
|
||||
return V_URLDecodeInternal(pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void V_StripExtension( std::string &in )
|
||||
void V_StripExtension(std::string &in)
|
||||
{
|
||||
// Find the last dot. If it's followed by a dot or a slash, then it's part of a
|
||||
// Find the last dot. If it's followed by a dot or a slash, then it's part of a
|
||||
// directory specifier like ../../somedir/./blah.
|
||||
std::string::size_type test = in.rfind( '.' );
|
||||
if ( test != std::string::npos )
|
||||
std::string::size_type test = in.rfind('.');
|
||||
if (test != std::string::npos)
|
||||
{
|
||||
// This handles things like ".\blah" or "c:\my@email.com\abc\def\geh"
|
||||
// Which would otherwise wind up with "" and "c:\my@email", respectively.
|
||||
if ( in.rfind( '\\' ) < test && in.rfind( '/' ) < test )
|
||||
if (in.rfind('\\') < test && in.rfind('/') < test)
|
||||
{
|
||||
in.resize( test );
|
||||
in.resize(test);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,45 +6,50 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
/** returns true if the string has the prefix */
|
||||
bool StringHasPrefix( const std::string & sString, const std::string & sPrefix );
|
||||
bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix );
|
||||
bool StringHasPrefix(const std::string &sString, const std::string &sPrefix);
|
||||
bool StringHasPrefixCaseSensitive(const std::string &sString, const std::string &sPrefix);
|
||||
|
||||
/** returns if the string has the suffix */
|
||||
bool StringHasSuffix( const std::string &sString, const std::string &sSuffix );
|
||||
bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix );
|
||||
bool StringHasSuffix(const std::string &sString, const std::string &sSuffix);
|
||||
bool StringHasSuffixCaseSensitive(const std::string &sString, const std::string &sSuffix);
|
||||
|
||||
/** converts a UTF-16 string to a UTF-8 string */
|
||||
std::string UTF16to8(const wchar_t * in);
|
||||
std::string UTF16to8(const wchar_t *in);
|
||||
|
||||
/** converts a UTF-8 string to a UTF-16 string */
|
||||
std::wstring UTF8to16(const char * in);
|
||||
std::wstring UTF8to16(const char *in);
|
||||
#define Utf16FromUtf8 UTF8to16
|
||||
|
||||
/** safely copy a string into a buffer */
|
||||
void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource );
|
||||
template< size_t bufferSize >
|
||||
void strcpy_safe( char (& buffer) [ bufferSize ], const char *pchSource )
|
||||
void strcpy_safe(char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource);
|
||||
template <size_t bufferSize>
|
||||
void strcpy_safe(char (&buffer)[bufferSize], const char *pchSource)
|
||||
{
|
||||
strcpy_safe( buffer, bufferSize, pchSource );
|
||||
strcpy_safe(buffer, bufferSize, pchSource);
|
||||
}
|
||||
|
||||
|
||||
/** converts a string to upper case */
|
||||
std::string StringToUpper( const std::string & sString );
|
||||
std::string StringToUpper(const std::string &sString);
|
||||
|
||||
/** converts a string to lower case */
|
||||
std::string StringToLower( const std::string & sString );
|
||||
std::string StringToLower(const std::string &sString);
|
||||
|
||||
// we stricmp (from WIN) but it isn't POSIX - OSX/LINUX have strcasecmp so just inline bridge to it
|
||||
#if defined( OSX ) || defined( LINUX )
|
||||
#ifndef __THROW // If __THROW is defined, these will clash with throw() versions on gcc
|
||||
#include <strings.h>
|
||||
inline int stricmp(const char *pStr1, const char *pStr2) { return strcasecmp(pStr1,pStr2); }
|
||||
#ifndef _stricmp
|
||||
#define _stricmp stricmp
|
||||
#endif
|
||||
inline int strnicmp( const char *pStr1, const char *pStr2, size_t unBufferLen ) { return strncasecmp( pStr1,pStr2, unBufferLen ); }
|
||||
#define _strnicmp strnicmp
|
||||
#if defined(OSX) || defined(LINUX)
|
||||
#ifndef __THROW // If __THROW is defined, these will clash with throw() versions on gcc
|
||||
#include <strings.h>
|
||||
inline int stricmp(const char *pStr1, const char *pStr2)
|
||||
{
|
||||
return strcasecmp(pStr1, pStr2);
|
||||
}
|
||||
#ifndef _stricmp
|
||||
#define _stricmp stricmp
|
||||
#endif
|
||||
inline int strnicmp(const char *pStr1, const char *pStr2, size_t unBufferLen)
|
||||
{
|
||||
return strncasecmp(pStr1, pStr2, unBufferLen);
|
||||
}
|
||||
#define _strnicmp strnicmp
|
||||
#endif
|
||||
|
||||
#ifndef _vsnprintf_s
|
||||
@@ -53,9 +58,9 @@ std::string StringToLower( const std::string & sString );
|
||||
|
||||
#define _TRUNCATE ((size_t)-1)
|
||||
|
||||
#endif // defined( OSX ) || defined( LINUX )
|
||||
#endif // defined( OSX ) || defined( LINUX )
|
||||
|
||||
#if defined( OSX )
|
||||
#if defined(OSX)
|
||||
// behaviors ensure NULL-termination at least as well as _TRUNCATE does, but
|
||||
// wcsncpy_s/strncpy_s can non-NULL-terminate, wcslcpy/strlcpy can not.
|
||||
inline errno_t wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count)
|
||||
@@ -70,63 +75,64 @@ inline errno_t strncpy_s(char *strDest, size_t numberOfElements, const char *str
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( LINUX )
|
||||
// this implementation does not return whether or not the destination was
|
||||
#if defined(LINUX)
|
||||
// this implementation does not return whether or not the destination was
|
||||
// truncated, but that is straightforward to fix if anybody actually needs the
|
||||
// return code.
|
||||
// return code.
|
||||
#include "string.h"
|
||||
inline void wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count)
|
||||
{
|
||||
wcsncpy(strDest, strSource, numberOfElements);
|
||||
strDest[numberOfElements-1] = '\0';
|
||||
strDest[numberOfElements - 1] = '\0';
|
||||
}
|
||||
|
||||
inline void strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count)
|
||||
{
|
||||
strncpy(strDest, strSource, numberOfElements);
|
||||
strDest[numberOfElements-1] = '\0';
|
||||
strDest[numberOfElements - 1] = '\0';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( _WIN32 ) && _MSC_VER < 1800
|
||||
inline uint64_t strtoull(const char *str, char **endptr, int base) { return _strtoui64( str, endptr, base ); }
|
||||
#if defined(_WIN32) && _MSC_VER < 1800
|
||||
inline uint64_t strtoull(const char *str, char **endptr, int base)
|
||||
{
|
||||
return _strtoui64(str, endptr, base);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handles copying a std::string into a buffer as would be provided in an API */
|
||||
uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen );
|
||||
uint32_t ReturnStdString(const std::string &sValue, char *pchBuffer, uint32_t unBufferLen);
|
||||
|
||||
/* Handles copying a buffer into an std::string and auto adds null terminator */
|
||||
void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen );
|
||||
void BufferToStdString(std::string &sDest, const char *pchBuffer, uint32_t unBufferLen);
|
||||
|
||||
/** Returns a std::string from a uint64_t */
|
||||
std::string Uint64ToString( uint64_t ulValue );
|
||||
std::string Uint64ToString(uint64_t ulValue);
|
||||
|
||||
/** returns a uint64_t from a string */
|
||||
uint64_t StringToUint64( const std::string & sValue );
|
||||
uint64_t StringToUint64(const std::string &sValue);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
|
||||
// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
|
||||
// This version of the call isn't a strict RFC implementation, but uses + for space as is
|
||||
// the standard in HTML form encoding, despite it not being part of the RFC.
|
||||
//
|
||||
// Dest buffer should be at least as large as source buffer to guarantee room for decode.
|
||||
//-----------------------------------------------------------------------------
|
||||
void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen );
|
||||
void V_URLEncode(char *pchDest, int nDestLen, const char *pchSource, int nSourceLen);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
|
||||
// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.
|
||||
// This version of the call isn't a strict RFC implementation, but uses + for space as is
|
||||
// the standard in HTML form encoding, despite it not being part of the RFC.
|
||||
//
|
||||
// Dest buffer should be at least as large as source buffer to guarantee room for decode.
|
||||
// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen );
|
||||
size_t V_URLDecode(char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strip extension from a path
|
||||
//-----------------------------------------------------------------------------
|
||||
void V_StripExtension( std::string &in );
|
||||
|
||||
|
||||
void V_StripExtension(std::string &in);
|
||||
|
||||
Reference in New Issue
Block a user