Efficient image padding in C
I have made some changes to the code I feel make things more clear, I will post them here in case someone needs something similar.

Code below is used in my function and is work of Freek van Tienen (part of open source software Paparazzi):

struct image_t {
  enum image_type type;   ///&lt; The image type
  uint16_t w;             ///&lt; Image width
  uint16_t h;             ///&lt; Image height
  struct timeval ts;      ///&lt; The timestamp of creation

  uint8_t buf_idx;        ///&lt; Buffer index for V4L2 freeing
  uint32_t buf_size;      ///&lt; The buffer size
  void *buf;              ///&lt; Image buffer (depending on the image_type)
};

void image_create(struct image_t *img, uint16_t width, uint16_t height, enum image_type type)
{
  // Set the variables
  img-&gt;type = type;
  img-&gt;w = width;
  img-&gt;h = height;


  // Depending on the type the size differs
  if (type == IMAGE_YUV422) {
    img-&gt;buf_size = sizeof(uint8_t) * 2 * width * height;
  } else if (type == IMAGE_JPEG) {
    img-&gt;buf_size = sizeof(uint8_t) * 2 * width * height;  // At maximum quality this is enough
  } else if (type == IMAGE_GRADIENT) {
    img-&gt;buf_size = sizeof(int16_t) * width * height;
  } else {
    img-&gt;buf_size = sizeof(uint8_t) * width * height;
  }

  img-&gt;buf = malloc(img-&gt;buf_size);
}


My code for image padding:

void pad_image(struct image_t *input, struct image_t *output, uint8_t expand)
{
    image_create(output, input-&gt;w + 2 * expand, input-&gt;h + 2 * expand, input-&gt;type);

    uint8_t *input_buf = (uint8_t *)input-&gt;buf;
    uint8_t *output_buf = (uint8_t *)output-&gt;buf;

    // Skip first `expand` rows, iterate through next input-&gt;h rows
    for (uint16_t i = expand; i != (output-&gt;h - expand); i++){

        // Mirror first `expand` columns
        for (uint8_t j = 0; j != expand; j++)
            output_buf[i * output-&gt;w + (expand - 1 - j)] = input_buf[(i - expand) * input-&gt;w + j];

        // Copy corresponding row values from input image
        memcpy(&amp;output_buf[i * output-&gt;w + expand], &amp;input_buf[(i - expand) * input-&gt;w], sizeof(uint8_t) * input-&gt;w);

        // Mirror last `expand` columns
        for (uint8_t j = 0; j != expand; j++)
            output_buf[i * output-&gt;w + output-&gt;w - expand + j] = output_buf[i * output-&gt;w + output-&gt;w - expand -1 - j];
    }

    // Mirror first `expand` and last `expand` rows
    for (uint8_t i = 0; i != expand; i++){
        memcpy(&amp;output_buf[(expand - 1) * output-&gt;w - i * output-&gt;w], &amp;output_buf[expand * output-&gt;w + i * output-&gt;w], sizeof(uint8_t) * output-&gt;w);
        memcpy(&amp;output_buf[(output-&gt;h - expand) * output-&gt;w + i * output-&gt;w], &amp;output_buf[(output-&gt;h - expand - 1) * output-&gt;w - i * output-&gt;w], sizeof(uint8_t) * output-&gt;w);
    }
}