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:
erwincoumans
2018-09-23 14:17:31 -07:00
parent b73b05e9fb
commit ab8f16961e
1773 changed files with 1081087 additions and 474249 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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 /////////////////////////////////////////////////////////////

View File

@@ -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

View File

@@ -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*/
/*

View File

@@ -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
}

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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);