diff --git a/encoder/mjpeg_encoder.cpp b/encoder/mjpeg_encoder.cpp index edf5db87..eba51ce3 100644 --- a/encoder/mjpeg_encoder.cpp +++ b/encoder/mjpeg_encoder.cpp @@ -70,40 +70,20 @@ void MjpegEncoder::encodeJPEG(struct jpeg_compress_struct &cinfo, EncodeItem &it uint8_t *Y = (uint8_t *)item.mem; uint8_t *U = (uint8_t *)Y + item.stride * item.height; uint8_t *V = (uint8_t *)U + stride2 * (item.height / 2); + uint8_t *Y_max = U - item.stride; + uint8_t *U_max = V - stride2; + uint8_t *V_max = U_max + stride2 * (item.height / 2); JSAMPROW y_rows[16]; JSAMPROW u_rows[8]; JSAMPROW v_rows[8]; - unsigned int height_align = item.height & ~15; - while (cinfo.next_scanline < height_align) + for (uint8_t *Y_row = Y, *U_row = U, *V_row = V; cinfo.next_scanline < item.height;) { - uint8_t *Y_row = Y + cinfo.next_scanline * item.stride; for (int i = 0; i < 16; i++, Y_row += item.stride) - y_rows[i] = Y_row; - uint8_t *U_row = U + (cinfo.next_scanline / 2) * stride2; - uint8_t *V_row = V + (cinfo.next_scanline / 2) * stride2; + y_rows[i] = std::min(Y_row, Y_max); for (int i = 0; i < 8; i++, U_row += stride2, V_row += stride2) - u_rows[i] = U_row, v_rows[i] = V_row; - - JSAMPARRAY rows[] = { y_rows, u_rows, v_rows }; - jpeg_write_raw_data(&cinfo, rows, 16); - } - if (cinfo.next_scanline < item.height) - { - // Raw data has to be written in blocks of 16 rows, so rows beyond the highest - // multiple of 16 have to be copied to a 16-row sized buffer and then added. - std::vector y_pixels(16 * item.stride); - std::vector u_pixels(8 * stride2); - std::vector v_pixels(8 * stride2); - memcpy(&y_pixels[0], Y + height_align * item.stride, (item.height & 15) * item.stride); - memcpy(&u_pixels[1], U + height_align / 2 * stride2, (item.height & 15) / 2 * stride2); - memcpy(&v_pixels[1], V + height_align / 2 * stride2, (item.height & 15) / 2 * stride2); - - for (int i = 0; i < 16; i++) - y_rows[i] = &y_pixels[i * item.stride]; - for (int i = 0; i < 8; i++) - u_rows[i] = &u_pixels[i * stride2], v_rows[i] = &v_pixels[i * stride2]; + u_rows[i] = std::min(U_row, U_max), v_rows[i] = std::min(V_row, V_max); JSAMPARRAY rows[] = { y_rows, u_rows, v_rows }; jpeg_write_raw_data(&cinfo, rows, 16); diff --git a/image/jpeg.cpp b/image/jpeg.cpp index 9f1e3a6f..d3a28699 100644 --- a/image/jpeg.cpp +++ b/image/jpeg.cpp @@ -332,40 +332,20 @@ static void YUV420_to_JPEG_fast(const uint8_t *input, const unsigned int width, uint8_t *Y = (uint8_t *)input; uint8_t *U = (uint8_t *)Y + stride * height; uint8_t *V = (uint8_t *)U + stride2 * (height / 2); + uint8_t *Y_max = U - stride; + uint8_t *U_max = V - stride2; + uint8_t *V_max = U_max + stride2 * (height / 2); JSAMPROW y_rows[16]; JSAMPROW u_rows[8]; JSAMPROW v_rows[8]; - unsigned int height_align = height & ~15; - while (cinfo.next_scanline < height_align) + for (uint8_t *Y_row = Y, *U_row = U, *V_row = V; cinfo.next_scanline < height;) { - uint8_t *Y_row = Y + cinfo.next_scanline * stride; for (int i = 0; i < 16; i++, Y_row += stride) - y_rows[i] = Y_row; - uint8_t *U_row = U + (cinfo.next_scanline / 2) * stride2; - uint8_t *V_row = V + (cinfo.next_scanline / 2) * stride2; + y_rows[i] = std::min(Y_row, Y_max); for (int i = 0; i < 8; i++, U_row += stride2, V_row += stride2) - u_rows[i] = U_row, v_rows[i] = V_row; - - JSAMPARRAY rows[] = { y_rows, u_rows, v_rows }; - jpeg_write_raw_data(&cinfo, rows, 16); - } - if (cinfo.next_scanline < height) - { - // Raw data has to be written in blocks of 16 rows, so rows beyond the highest - // multiple of 16 have to be copied to a 16-row sized buffer and then added. - std::vector y_pixels(16 * stride); - std::vector u_pixels(8 * stride2); - std::vector v_pixels(8 * stride2); - memcpy(&y_pixels[0], Y + height_align * stride, (height & 15) * stride); - memcpy(&u_pixels[1], U + height_align / 2 * stride2, (height & 15) / 2 * stride2); - memcpy(&v_pixels[1], V + height_align / 2 * stride2, (height & 15) / 2 * stride2); - - for (int i = 0; i < 16; i++) - y_rows[i] = &y_pixels[i * stride]; - for (int i = 0; i < 8; i++) - u_rows[i] = &u_pixels[i * stride2], v_rows[i] = &v_pixels[i * stride2]; + u_rows[i] = std::min(U_row, U_max), v_rows[i] = std::min(V_row, V_max); JSAMPARRAY rows[] = { y_rows, u_rows, v_rows }; jpeg_write_raw_data(&cinfo, rows, 16);