La manera más fácil que he encontrado para resolver este problema, aunque no sé cómo Adobe fuerza a él, es el uso de una estructura de datos persistentes, así:

Se piensa una imagen como una colección de mosaicos de imágenes, digamos 64x64 píxeles cada uno, y se obtiene la basura recogida o referencia contada (por ejemplo, usando shared_ptr
en C++).
Ahora, cuando el usuario realiza cambios en un mosaico de imagen, se crea una nueva versión mientras copia superficial de las baldosas sin modificar:

Todo excepto aquellas tejas oscuras son poco profundas copiado en un cambio de este tipo. Y cuando lo haces de esa manera, su sistema de deshacer todo se reduce a esto:
before user operation:
store current image in undo stack
on undo/redo:
swap image at top of undo stack with current image
y se hace muy fácil de esa manera, sin necesidad de toda la imagen a almacenar una y otra vez en cada entrada de deshacer. Como ventaja adicional, cuando los usuarios copian y pegan capas, apenas necesitan más memoria a menos que/hasta que realicen cambios en esa capa pegada. Básicamente, le proporciona un sistema de instancias para las imágenes. Como una ventaja adicional, cuando un usuario crea una capa transparente que es, por ejemplo, 2000x2000 píxeles, solo pinta un poco de la imagen, como por ejemplo 100x100 píxeles, que apenas toma memoria porque las casillas vacías/transparentes no tiene que almacenar cualquier píxel, solo un par de punteros nulos. También acelera la composición con esas capas en su mayoría transparentes, porque no tienes que mezclar alfa los mosaicos vacíos de la imagen y puedes omitirlos. También acelera los filtros de imagen en esos casos, ya que también pueden saltear las baldosas vacías.
En cuanto a las acciones de PS, ese es un enfoque un poco diferente. Allí puede usar algunas secuencias de comandos para indicar qué acciones realizar, pero puede acoplarlas con las de arriba para almacenar en caché solo las partes modificadas de la imagen. El objetivo de este enfoque es evitar tener que copiar en profundidad la totalidad de la imagen una y otra vez e inflar el uso de memoria para almacenar en caché los estados previos de una imagen para deshacer sin tener que jugar con la escritura de la lógica deshacer/rehacer para todo tipo de diferentes operaciones que podrían ocurrir
¿Por qué cerrar? ¿Esto es un engaño o algo así? El cierre debe ir seguido de los comentarios –
Eche un vistazo a [este subproceso SO] (http://stackoverflow.com/questions/3541383/undo-redo-implementation/3542670#3542670). – Lazer