para abrir .pgm e .ppm precisas de uma biblioteca especifica para isso, procura no google, deve haver milhares delas.
independentemente da biblioteca usada normalemnte funcionam desta maneira. fazem loading da imagem para um buffer e tu tens acesso a todos os pixeis nesse buffer em que uma data posição X, Y te dá uma cor.
por exemplo para rodar 90º no sentido dos ponteiros do relogio, isto funciona para qualquer biblioteca, abres a imagem e começas a ler o buffer com 2 for's desde (0, 0) até (image.height - 1, image.width - 1) e para cada posição multiplicas pela matrix rotação
[0, 1]
[-1, 0]
(matriz rotação no sentido dos ponteiros do relogio é R (-A) = [cos A, sin A][-sin A, cos A] sendo A = angulo
e vai-te dar uma nova posição, essa posição num novo buffer vai ter a cor igual ao pixel que tas a ler no buffer original.
PS: para mais informações sobre trsnformações lê uma introdução basica sobre mnatrizes e transformações em algebra, é tipo o basico para manipulação de graficos seja 2d ou 3d