LibYuv: Updates to general functionality.
Review URL: http://webrtc-codereview.appspot.com/219003
git-svn-id: http://libyuv.googlecode.com/svn/trunk@18 16f28f9a-4ce2-e073-06de-1de4eb20be90
diff --git a/include/general.h b/include/general.h
index b7227bf..253f27e 100644
--- a/include/general.h
+++ b/include/general.h
@@ -23,36 +23,33 @@
// Supported rotation
enum VideoRotationMode
{
- kRotateNone = 0,
- kRotateClockwise = 90,
- kRotateAntiClockwise = -90,
- kRotate180 = 180,
+ kRotateNone = 0,
+ kRotateClockwise = 90,
+ kRotateCounterClockwise = -90,
+ kRotate180 = 180,
};
-// Mirror functions
-// The following 2 functions perform mirroring on an image (LeftRight/UpDown)
-// Input:
-// - width : Image width in pixels.
-// - height : Image height in pixels.
-// - inFrame : Reference to input image.
-// - outFrame : Reference to converted image.
-// Return value: 0 if OK, < 0 otherwise.
+// I420 mirror
int
-MirrorI420LeftRight(const uint8* src_frame, int src_stride,
- uint8* dst_frame, int dst_stride,
- int src_width, int src_height);
+I420Mirror(const uint8* src_yplane, int src_ystride,
+ const uint8* src_uplane, int src_ustride,
+ const uint8* src_vplane, int src_vstride,
+ uint8* dst_yplane, int dst_ystride,
+ uint8* dst_uplane, int dst_ustride,
+ uint8* dst_vplane, int dst_vstride,
+ int width, int height);
-// Cut/Pad I420 frame to match desird dimensions.
+// Crop/Pad I420 frame to match required dimensions.
int
-CutPadI420Frame(const uint8* inFrame, int inWidth,
- int inHeight, uint8* outFrame,
- int outWidth, int outHeight);
+I420CropPad(const uint8* src_frame, int src_width,
+ int src_height, uint8* dst_frame,
+ int dst_width, int dst_height);
-// I420 Cut - make a center cut
+// I420 Crop - make a center cut
int
-CutI420Frame(uint8* frame, int fromWidth,
- int fromHeight, int toWidth,
- int toHeight);
+I420Cut(uint8* frame,
+ int src_width, int src_height,
+ int dst_width, int dst_height);
} // namespace libyuv
diff --git a/source/general.cc b/source/general.cc
index 13b628b..7bc63ed 100644
--- a/source/general.cc
+++ b/source/general.cc
@@ -10,329 +10,299 @@
#include "general.h"
-#include <assert.h>
#include <string.h> // memcpy(), memset()
-#include "video_common.h"
-
namespace libyuv {
-
int
-MirrorI420LeftRight( const uint8* src_frame,uint8* dst_frame,
- int src_width, int src_height)
+I420Mirror(const uint8* src_yplane, int src_ystride,
+ const uint8* src_uplane, int src_ustride,
+ const uint8* src_vplane, int src_vstride,
+ uint8* dst_yplane, int dst_ystride,
+ uint8* dst_uplane, int dst_ustride,
+ uint8* dst_vplane, int dst_vstride,
+ int width, int height)
{
- if (src_width < 1 || src_height < 1)
- {
- return -1;
+ if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
+ dst_yplane == NULL || dst_uplane == NULL || dst_vplane == NULL)
+ return -1;
+
+ int indO = 0;
+ int indS = 0;
+ int wind, hind;
+ uint8 tmpVal, tmpValU, tmpValV;
+ // Will swap two values per iteration
+ const int halfWidth = (width + 1) >> 1;
+
+ // Y
+ for (wind = 0; wind < halfWidth; wind++){
+ for (hind = 0; hind < height; hind++){
+ indO = hind * src_ystride + wind;
+ indS = hind * dst_ystride + (width - wind - 1);
+ tmpVal = src_yplane[indO];
+ dst_yplane[indO] = src_yplane[indS];
+ dst_yplane[indS] = tmpVal;
}
+ }
- assert(src_width % 2 == 0 && src_height % 2 == 0);
+ const int halfHeight = (height + 1) >> 1;
+ const int halfSrcuvStride = (height + 1) >> 1;
+ const int halfuvWidth = (width + 1) >> 2;
- int indO = 0;
- int indS = 0;
- int wind, hind;
- uint8 tmpVal;
- // Will swap two values per iteration
- const int halfW = src_width >> 1;
- const int halfStride = src_width >> 1;
- // Y
- for (wind = 0; wind < halfW; wind++ )
- {
- for (hind = 0; hind < src_height; hind++ )
- {
- indO = hind * src_width + wind;
- indS = hind * src_width + (src_width - wind - 1); // swapping index
- tmpVal = src_frame[indO];
- dst_frame[indO] = src_frame[indS];
- dst_frame[indS] = tmpVal;
- } // end for (height)
- } // end for(width)
- const int lengthW = src_width >> 2;
- const int lengthH = src_height >> 1;
- // V
- int zeroInd = src_width * src_height;
- for (wind = 0; wind < lengthW; wind++ )
- {
- for (hind = 0; hind < lengthH; hind++ )
- {
- indO = zeroInd + hind * halfW + wind;
- indS = zeroInd + hind * halfW + (halfW - wind - 1);// swapping index
- tmpVal = src_frame[indO];
- dst_frame[indO] = src_frame[indS];
- dst_frame[indS] = tmpVal;
- } // end for (height)
- } // end for(width)
-
- // U
- zeroInd += src_width * src_height >> 2;
- for (wind = 0; wind < lengthW; wind++ )
- {
- for (hind = 0; hind < lengthH; hind++ )
- {
- indO = zeroInd + hind * halfW + wind;
- indS = zeroInd + hind * halfW + (halfW - wind - 1);// swapping index
- tmpVal = src_frame[indO];
- dst_frame[indO] = src_frame[indS];
- dst_frame[indS] = tmpVal;
- } // end for (height)
- } // end for(width)
-
- return 0;
+ for (wind = 0; wind < halfuvWidth; wind++){
+ for (hind = 0; hind < halfHeight; hind++){
+ indO = hind * halfSrcuvStride + wind;
+ indS = hind * halfSrcuvStride + (halfuvWidth - wind - 1);
+ // U
+ tmpValU = src_uplane[indO];
+ dst_uplane[indO] = src_uplane[indS];
+ dst_uplane[indS] = tmpValU;
+ // V
+ tmpValV = src_vplane[indO];
+ dst_vplane[indO] = src_vplane[indS];
+ dst_vplane[indS] = tmpValV;
+ }
+ }
+ return 0;
}
-
// Make a center cut
int
-CutI420Frame(uint8* frame,
- int fromWidth, int fromHeight,
- int toWidth, int toHeight)
+I420Cut(uint8* frame,
+ int src_width, int src_height,
+ int dst_width, int dst_height)
{
- if (toWidth < 1 || fromWidth < 1 || toHeight < 1 || fromHeight < 1 )
- {
- return -1;
- }
- if (toWidth == fromWidth && toHeight == fromHeight)
- {
- // Nothing to do
- return 3 * toHeight * toWidth / 2;
- }
- if (toWidth > fromWidth || toHeight > fromHeight)
- {
- // error
- return -1;
- }
- int i = 0;
- int m = 0;
- int loop = 0;
- int halfToWidth = toWidth / 2;
- int halfToHeight = toHeight / 2;
- int halfFromWidth = fromWidth / 2;
- int halfFromHeight= fromHeight / 2;
- int cutHeight = ( fromHeight - toHeight ) / 2;
- int cutWidth = ( fromWidth - toWidth ) / 2;
+ if (frame == NULL)
+ return -1;
- for (i = fromWidth * cutHeight + cutWidth; loop < toHeight ;
- loop++, i += fromWidth)
- {
- memcpy(&frame[m],&frame[i],toWidth);
- m += toWidth;
- }
- i = fromWidth * fromHeight; // ilum
- loop = 0;
- for ( i += (halfFromWidth * cutHeight / 2 + cutWidth / 2);
- loop < halfToHeight; loop++,i += halfFromWidth)
- {
- memcpy(&frame[m],&frame[i],halfToWidth);
- m += halfToWidth;
- }
- loop = 0;
- i = fromWidth * fromHeight + halfFromHeight * halfFromWidth; // ilum + Cr
- for ( i += (halfFromWidth * cutHeight / 2 + cutWidth / 2);
- loop < halfToHeight; loop++, i += halfFromWidth)
- {
- memcpy(&frame[m],&frame[i],halfToWidth);
- m += halfToWidth;
- }
- return halfToWidth * toHeight * 3;
+ if (src_width == dst_width && src_height == dst_height){
+ // Nothing to do
+ return 3 * dst_height * dst_width / 2;
+ }
+ if (dst_width > src_width || dst_height > src_height){
+ // error
+ return -1;
+ }
+ int i = 0;
+ int m = 0;
+ int loop = 0;
+ int half_dst_width = dst_width / 2;
+ int halfdst_height = dst_height / 2;
+ int halfsrc_width = src_width / 2;
+ int half_dst_height= src_height / 2;
+ int crop_height = ( src_height - dst_height ) / 2;
+ int crop_width = ( src_width - dst_width ) / 2;
+
+ for (i = src_width * crop_height + crop_width; loop < dst_height ;
+ loop++, i += src_width){
+ memcpy(&frame[m],&frame[i],dst_width);
+ m += dst_width;
+ }
+ i = src_width * src_height; // ilum
+ loop = 0;
+ for ( i += (halfsrc_width * crop_height / 2 + crop_width / 2);
+ loop < halfdst_height; loop++,i += halfsrc_width){
+ memcpy(&frame[m],&frame[i],half_dst_width);
+ m += half_dst_width;
+ }
+ loop = 0;
+ i = src_width * src_height + half_dst_height * halfsrc_width; // ilum + Cr
+ for ( i += (halfsrc_width * crop_height / 2 + crop_width / 2);
+ loop < halfdst_height; loop++, i += halfsrc_width){
+ memcpy(&frame[m],&frame[i],half_dst_width);
+ m += half_dst_width;
+ }
+ return 0;
}
+
int
-CutPadI420Frame(const uint8* inFrame, int inWidth,
- int inHeight, uint8* outFrame,
- int outWidth, int outHeight)
+I420CropPad(const uint8* src_frame, int src_width,
+ int src_height, uint8* dst_frame,
+ int dst_width, int dst_height)
{
- if (inWidth < 1 || outWidth < 1 || inHeight < 1 || outHeight < 1 )
- {
- return -1;
- }
- if (inWidth == outWidth && inHeight == outHeight)
- {
- memcpy(outFrame, inFrame, 3 * outWidth * (outHeight >> 1));
+ if (src_width < 1 || dst_width < 1 || src_height < 1 || dst_height < 1 )
+ return -1;
+ if (src_width == dst_width && src_height == dst_height)
+ memcpy(dst_frame, src_frame, 3 * dst_width * (dst_height >> 1));
+ else
+ {
+ if ( src_height < dst_height){
+ // pad height
+ int pad_height = dst_height - src_height;
+ int i = 0;
+ int pad_width = 0;
+ int crop_width = 0;
+ int width = src_width;
+ if (src_width < dst_width){
+ // pad width
+ pad_width = dst_width - src_width;
+ } else{
+ // cut width
+ crop_width = src_width - dst_width;
+ width = dst_width;
+ }
+ if (pad_height){
+ memset(dst_frame, 0, dst_width * (pad_height >> 1));
+ dst_frame += dst_width * (pad_height >> 1);
+ }
+ for (i = 0; i < src_height;i++)
+ {
+ if (pad_width)
+ {
+ memset(dst_frame, 0, pad_width / 2);
+ dst_frame += pad_width / 2;
+ }
+ src_frame += crop_width >> 1; // in case we have a cut
+ memcpy(dst_frame,src_frame ,width);
+ src_frame += crop_width >> 1;
+ dst_frame += width;
+ src_frame += width;
+ if (pad_width)
+ {
+ memset(dst_frame, 0, pad_width / 2);
+ dst_frame += pad_width / 2;
+ }
+ }
+ if (pad_height)
+ {
+ memset(dst_frame, 0, dst_width * (pad_height >> 1));
+ dst_frame += dst_width * (pad_height >> 1);
+ }
+ if (pad_height)
+ {
+ memset(dst_frame, 127, (dst_width >> 2) * (pad_height >> 1));
+ dst_frame += (dst_width >> 2) * (pad_height >> 1);
+ }
+ for (i = 0; i < (src_height >> 1); i++)
+ {
+ if (pad_width)
+ {
+ memset(dst_frame, 127, pad_width >> 2);
+ dst_frame += pad_width >> 2;
+ }
+ src_frame += crop_width >> 2; // in case we have a cut
+ memcpy(dst_frame, src_frame,width >> 1);
+ src_frame += crop_width >> 2;
+ dst_frame += width >> 1;
+ src_frame += width >> 1;
+ if (pad_width)
+ {
+ memset(dst_frame, 127, pad_width >> 2);
+ dst_frame += pad_width >> 2;
+ }
+ }
+ if (pad_height)
+ {
+ memset(dst_frame, 127, (dst_width >> 1) * (pad_height >> 1));
+ dst_frame += (dst_width >> 1) * (pad_height >> 1);
+ }
+ for (i = 0; i < (src_height >> 1); i++)
+ {
+ if (pad_width)
+ {
+ memset(dst_frame, 127, pad_width >> 2);
+ dst_frame += pad_width >> 2;
+ }
+ src_frame += crop_width >> 2; // in case we have a cut
+ memcpy(dst_frame, src_frame,width >> 1);
+ src_frame += crop_width >> 2;
+ dst_frame += width >> 1;
+ src_frame += width >> 1;
+ if (pad_width)
+ {
+ memset(dst_frame, 127, pad_width >> 2);
+ dst_frame += pad_width >> 2;
+ }
+ }
+ if (pad_height)
+ {
+ memset(dst_frame, 127, (dst_width >> 2) * (pad_height >> 1));
+ dst_frame += (dst_width >> 2) * (pad_height >> 1);
+ }
}
else
{
- if ( inHeight < outHeight)
- {
- // pad height
- int padH = outHeight - inHeight;
- int i = 0;
- int padW = 0;
- int cutW = 0;
- int width = inWidth;
- if (inWidth < outWidth)
- {
- // pad width
- padW = outWidth - inWidth;
- }
- else
- {
- // cut width
- cutW = inWidth - outWidth;
- width = outWidth;
- }
- if (padH)
- {
- memset(outFrame, 0, outWidth * (padH >> 1));
- outFrame += outWidth * (padH >> 1);
- }
- for (i = 0; i < inHeight;i++)
- {
- if (padW)
- {
- memset(outFrame, 0, padW / 2);
- outFrame += padW / 2;
- }
- inFrame += cutW >> 1; // in case we have a cut
- memcpy(outFrame,inFrame ,width);
- inFrame += cutW >> 1;
- outFrame += width;
- inFrame += width;
- if (padW)
- {
- memset(outFrame, 0, padW / 2);
- outFrame += padW / 2;
- }
- }
- if (padH)
- {
- memset(outFrame, 0, outWidth * (padH >> 1));
- outFrame += outWidth * (padH >> 1);
- }
- if (padH)
- {
- memset(outFrame, 127, (outWidth >> 2) * (padH >> 1));
- outFrame += (outWidth >> 2) * (padH >> 1);
- }
- for (i = 0; i < (inHeight >> 1); i++)
- {
- if (padW)
- {
- memset(outFrame, 127, padW >> 2);
- outFrame += padW >> 2;
- }
- inFrame += cutW >> 2; // in case we have a cut
- memcpy(outFrame, inFrame,width >> 1);
- inFrame += cutW >> 2;
- outFrame += width >> 1;
- inFrame += width >> 1;
- if (padW)
- {
- memset(outFrame, 127, padW >> 2);
- outFrame += padW >> 2;
- }
- }
- if (padH)
- {
- memset(outFrame, 127, (outWidth >> 1) * (padH >> 1));
- outFrame += (outWidth >> 1) * (padH >> 1);
- }
- for (i = 0; i < (inHeight >> 1); i++)
- {
- if (padW)
- {
- memset(outFrame, 127, padW >> 2);
- outFrame += padW >> 2;
- }
- inFrame += cutW >> 2; // in case we have a cut
- memcpy(outFrame, inFrame,width >> 1);
- inFrame += cutW >> 2;
- outFrame += width >> 1;
- inFrame += width >> 1;
- if (padW)
- {
- memset(outFrame, 127, padW >> 2);
- outFrame += padW >> 2;
- }
- }
- if (padH)
- {
- memset(outFrame, 127, (outWidth >> 2) * (padH >> 1));
- outFrame += (outWidth >> 2) * (padH >> 1);
- }
- }
- else
- {
- // cut height
- int i = 0;
- int padW = 0;
- int cutW = 0;
- int width = inWidth;
+ // cut height
+ int i = 0;
+ int pad_width = 0;
+ int crop_width = 0;
+ int width = src_width;
- if (inWidth < outWidth)
- {
- // pad width
- padW = outWidth - inWidth;
- } else
- {
- // cut width
- cutW = inWidth - outWidth;
- width = outWidth;
- }
- int diffH = inHeight - outHeight;
- inFrame += inWidth * (diffH >> 1); // skip top I
+ if (src_width < dst_width)
+ {
+ // pad width
+ pad_width = dst_width - src_width;
+ } else
+ {
+ // cut width
+ crop_width = src_width - dst_width;
+ width = dst_width;
+ }
+ int diff_height = src_height - dst_height;
+ src_frame += src_width * (diff_height >> 1); // skip top I
- for (i = 0; i < outHeight; i++)
- {
- if (padW)
- {
- memset(outFrame, 0, padW / 2);
- outFrame += padW / 2;
- }
- inFrame += cutW >> 1; // in case we have a cut
- memcpy(outFrame,inFrame ,width);
- inFrame += cutW >> 1;
- outFrame += width;
- inFrame += width;
- if (padW)
- {
- memset(outFrame, 0, padW / 2);
- outFrame += padW / 2;
- }
- }
- inFrame += inWidth * (diffH >> 1); // skip end I
- inFrame += (inWidth >> 2) * (diffH >> 1); // skip top of Cr
- for (i = 0; i < (outHeight >> 1); i++)
- {
- if (padW)
- {
- memset(outFrame, 127, padW >> 2);
- outFrame += padW >> 2;
- }
- inFrame += cutW >> 2; // in case we have a cut
- memcpy(outFrame, inFrame,width >> 1);
- inFrame += cutW >> 2;
- outFrame += width >> 1;
- inFrame += width >> 1;
- if (padW)
- {
- memset(outFrame, 127, padW >> 2);
- outFrame += padW >> 2;
- }
- }
- inFrame += (inWidth >> 2) * (diffH >> 1); // skip end of Cr
- inFrame += (inWidth >> 2) * (diffH >> 1); // skip top of Cb
- for (i = 0; i < (outHeight >> 1); i++)
- {
- if (padW)
- {
- memset(outFrame, 127, padW >> 2);
- outFrame += padW >> 2;
- }
- inFrame += cutW >> 2; // in case we have a cut
- memcpy(outFrame, inFrame, width >> 1);
- inFrame += cutW >> 2;
- outFrame += width >> 1;
- inFrame += width >> 1;
- if (padW)
- {
- memset(outFrame, 127, padW >> 2);
- outFrame += padW >> 2;
- }
- }
+ for (i = 0; i < dst_height; i++)
+ {
+ if (pad_width)
+ {
+ memset(dst_frame, 0, pad_width / 2);
+ dst_frame += pad_width / 2;
}
+ src_frame += crop_width >> 1; // in case we have a cut
+ memcpy(dst_frame,src_frame ,width);
+ src_frame += crop_width >> 1;
+ dst_frame += width;
+ src_frame += width;
+ if (pad_width)
+ {
+ memset(dst_frame, 0, pad_width / 2);
+ dst_frame += pad_width / 2;
+ }
+ }
+ src_frame += src_width * (diff_height >> 1); // skip end I
+ src_frame += (src_width >> 2) * (diff_height >> 1); // skip top of Cr
+ for (i = 0; i < (dst_height >> 1); i++)
+ {
+ if (pad_width)
+ {
+ memset(dst_frame, 127, pad_width >> 2);
+ dst_frame += pad_width >> 2;
+ }
+ src_frame += crop_width >> 2; // in case we have a cut
+ memcpy(dst_frame, src_frame,width >> 1);
+ src_frame += crop_width >> 2;
+ dst_frame += width >> 1;
+ src_frame += width >> 1;
+ if (pad_width)
+ {
+ memset(dst_frame, 127, pad_width >> 2);
+ dst_frame += pad_width >> 2;
+ }
+ }
+ src_frame += (src_width >> 2) * (diff_height >> 1); // skip end of Cr
+ src_frame += (src_width >> 2) * (diff_height >> 1); // skip top of Cb
+ for (i = 0; i < (dst_height >> 1); i++)
+ {
+ if (pad_width)
+ {
+ memset(dst_frame, 127, pad_width >> 2);
+ dst_frame += pad_width >> 2;
+ }
+ src_frame += crop_width >> 2; // in case we have a cut
+ memcpy(dst_frame, src_frame, width >> 1);
+ src_frame += crop_width >> 2;
+ dst_frame += width >> 1;
+ src_frame += width >> 1;
+ if (pad_width)
+ {
+ memset(dst_frame, 127, pad_width >> 2);
+ dst_frame += pad_width >> 2;
+ }
+ }
}
- return 3 * outWidth * (outHeight >> 1);
+ }
+ return 0;
}
} // nmaespace libyuv