+/*****************************************************************************
+ * Intra prediction for predictive lossless mode.
+ *****************************************************************************/
+
+/* Note that these functions take a shortcut (mc.copy instead of actual pixel prediction) which assumes
+ * that the edge pixels of the reconstructed frame are the same as that of the source frame. This means
+ * they will only work correctly if the neighboring blocks are losslessly coded. In practice, this means
+ * lossless mode cannot be mixed with lossy mode within a frame. */
+/* This can be resolved by explicitly copying the edge pixels after doing the mc.copy, but this doesn't
+ * need to be done unless we decide to allow mixing lossless and lossy compression. */
+
+void x264_predict_lossless_8x8_chroma( x264_t *h, int i_mode )
+{
+ int stride = h->fenc->i_stride[1] << h->mb.b_interlaced;
+ if( i_mode == I_PRED_CHROMA_V )
+ {
+ h->mc.copy[PIXEL_8x8]( h->mb.pic.p_fdec[1], FDEC_STRIDE, h->mb.pic.p_fenc_plane[1]-stride, stride, 8 );
+ h->mc.copy[PIXEL_8x8]( h->mb.pic.p_fdec[2], FDEC_STRIDE, h->mb.pic.p_fenc_plane[2]-stride, stride, 8 );
+ }
+ else if( i_mode == I_PRED_CHROMA_H )
+ {
+ h->mc.copy[PIXEL_8x8]( h->mb.pic.p_fdec[1], FDEC_STRIDE, h->mb.pic.p_fenc_plane[1]-1, stride, 8 );
+ h->mc.copy[PIXEL_8x8]( h->mb.pic.p_fdec[2], FDEC_STRIDE, h->mb.pic.p_fenc_plane[2]-1, stride, 8 );
+ }
+ else
+ {
+ h->predict_8x8c[i_mode]( h->mb.pic.p_fdec[1] );
+ h->predict_8x8c[i_mode]( h->mb.pic.p_fdec[2] );
+ }
+}
+
+void x264_predict_lossless_4x4( x264_t *h, uint8_t *p_dst, int idx, int i_mode )
+{
+ int stride = h->fenc->i_stride[0] << h->mb.b_interlaced;
+ uint8_t *p_src = h->mb.pic.p_fenc_plane[0] + block_idx_x[idx]*4 + block_idx_y[idx]*4 * stride;
+
+ if( i_mode == I_PRED_4x4_V )
+ h->mc.copy[PIXEL_4x4]( p_dst, FDEC_STRIDE, p_src-stride, stride, 4 );
+ else if( i_mode == I_PRED_4x4_H )
+ h->mc.copy[PIXEL_4x4]( p_dst, FDEC_STRIDE, p_src-1, stride, 4 );
+ else
+ h->predict_4x4[i_mode]( p_dst );
+}
+
+void x264_predict_lossless_8x8( x264_t *h, uint8_t *p_dst, int idx, int i_mode, uint8_t edge[33] )
+{
+ int stride = h->fenc->i_stride[0] << h->mb.b_interlaced;
+ uint8_t *p_src = h->mb.pic.p_fenc_plane[0] + (idx&1)*8 + (idx>>1)*8*stride;
+
+ if( i_mode == I_PRED_8x8_V )
+ h->mc.copy[PIXEL_8x8]( p_dst, FDEC_STRIDE, p_src-stride, stride, 8 );
+ else if( i_mode == I_PRED_8x8_H )
+ h->mc.copy[PIXEL_8x8]( p_dst, FDEC_STRIDE, p_src-1, stride, 8 );
+ else
+ h->predict_8x8[i_mode]( p_dst, edge );
+}
+
+void x264_predict_lossless_16x16( x264_t *h, int i_mode )
+{
+ int stride = h->fenc->i_stride[0] << h->mb.b_interlaced;
+ if( i_mode == I_PRED_16x16_V )
+ h->mc.copy[PIXEL_16x16]( h->mb.pic.p_fdec[0], FDEC_STRIDE, h->mb.pic.p_fenc_plane[0]-stride, stride, 16 );
+ else if( i_mode == I_PRED_16x16_H )
+ h->mc.copy_16x16_unaligned( h->mb.pic.p_fdec[0], FDEC_STRIDE, h->mb.pic.p_fenc_plane[0]-1, stride, 16 );
+ else
+ h->predict_16x16[i_mode]( h->mb.pic.p_fdec[0] );
+}
+