The effect in the photo is very close to a simple scale-bias per pixel. After a bit of tweaking, I found that applying the transformation: $x' = 0.77x + 38$ to the raw pixel values (as bytes) gives something quite close to your output:
In this case the effect of the scale-bias is to reduce the contrast (scale factor < 1) while keeping the overall brightness about the same.
Example Python code (with numpy and pillow) to do this transformation:
import numpy as np
from PIL import Image
a = np.array(Image.open("input.png"), dtype=np.float32)
b = a * 0.77 + 38
Image.fromarray(np.uint8(np.rint(b))).save("output.png")
For learning how to implement many basic image processing operations, I've found these Image Processing Operator Worksheets from the University of Edinburgh helpful.