I would start defining some nice structure for storing images that is also able to map sub images into the original data;
e.g.
struct Img{
int width;
int height;
int rowstep; ///< in multiples of pixel data type
int* data; ///< ptr type may be different or void
};
Then i would read/convert the data from the file into some memory (parse the image value) and create a toplevel img:
Img toplevel {4,4, 32, dataptr};
4 subimges:
Img tl {toplevel.width/2,toplevel.height/2, toplevel.rowstep, toplevel.data};
Img tr {toplevel.width/2,toplevel.height/2, toplevel.rowstep, toplevel.data+toplevel.width/2};
Img bl {toplevel.width/2,toplevel.height/2, toplevel.rowstep, toplevel.data + toplevel.rowstep*toplevel.height/2};
Img br {toplevel.width/2,toplevel.height/2, toplevel.rowstep, toplevel.data + toplevel.rowstep*toplevel.height/2 + toplevel.width/2};
You can now recursivly split each img into 4 smaller as long as the width is greater 1 (recursive descent).
Then you have the color value for the leafs.
On the recursive ascension you can sum/mean the 4 values from the deeper levels (and throw away the sub images if you do not need them).
At the end you should have a complete quadtree.
PS:
One additional comment:
I would try not to use raw-Pointer in the Quadtree structure.
Maybe use std::array<std::shared_ptr<QuadTreeNode>, 4> children;