Strange Behaviour of glTexSubImage3D


i am striking a problem, which i can’t figure out by myself.
The situation is like this. I create a 2D array texture, for which i allocate memory with (glTexStorage3D). The Texture has got one Mip-Map level and measures 16x16 texels. The format of the texture is RGB8UI.
What i am trying to do now is to update the subregion starting at (0,0) to (14,14). Therefore i create an char array of size 15 * 15 * 3 ( matching the RGB8UI format). The array is filled in such a way, that the first row and the 15th column gets filled with ones. The others get filled with zeros. I then call

glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 15, 15, 1, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);

There is data uploaded, but it seems, that the 16th column is filled by the data too, so that on the next row the 16th element of the data array (data[15]) is copied into the texel (15, 0) instead of (0, 1).
If i specify data as an array of 16163 elements everything works fine. I am losing my mind. Whats going on here?

Some details:

//Create texture
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8UI, 16, 16, 5);
unsigned int p = 15;
for (unsigned int k = 0; k < 5; k++, gridSpacing *= 2) {
   char* heightData = new char[p * p * 3];
   unsigned int rowStride = p * 3;

   for (unsigned int i = 0; i < p; i++) {
      for (unsigned int j = 0; j < p; j++) {
         if (i == 0 || j == 0)
	    heightData[i * rowStride + j * 3] = 1;
            heightData[i * rowStride + j * 3] = 0;

// Binding 

// Upload texture data
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, k, 15, 15, 1, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, heightData);

delete[] heightData;

Some pictures to demonstrate the problem. Row 0 and column 15 should be lifted by 1, which is correctly done in the first picture. In the second picture you see a diagonal, but the first row seems to be correctly lifted. You can also see, that there is some garbage data in the texture (the big lines going up in the air): (Sorry i am not allowed to upload any pictures.)

OpenGL by default expects each pixel row to be aligned on a 4-byte boundary. Since you have a width of 15 and each component is 3 bytes, the combined length is 45 bytes, so it expects 3 bytes of padding before the next row starts. When the width is 16, it works okay because 16*3 = 48 which is a multiple of 4.

Check out glPixelStore for details of how OpenGL decides how to retrieve/store data. You could ensure you have correct padding, but a simple fix would be to call:

glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

I was still fixing the errors in my post and you already gave me the answer.
Thank you very much, i’ll try this out.

Edit: As expected: It solved my problem. Thanks again : )