; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; Sources.JPEG
;   14th September 1993 WRS - started
;    1st November  1993 WRS - modified to simplify memory allocation interface
; Some parts of JPEG decoding are done in C, code in Sources.PutScaled
; provides assistance for debugging output.

      [ jpeg

; ----------------------------------------------------------------------
; R1->sprite
; Preserve all registers
; Need to set up, for entry into the C code:
; static int jpeg_scan_file(
;   decompress_info_ptr cinfo,      in r0
;   char *file_image,                  r1
;   int image_length,                  r2
;   int xmin,                          r3
;   int xmax,                          [sp,#0]
;   int width,                         [sp,#4]
;   int height,                        [sp,#6]
;   BOOL dc_only);                     [sp,#8]
;   lr = wp value from the assembler
;   On exit the stack arguments will have been removed for us.
;jpeg_scan
;        Push    "R0-R12,LR"
;        ; get ready to call C code
;        MOV     SL,R12                           ; will be left alone by compiled C - for debug routines above.
;        ADRL    R3,ccompiler_sp
;        ADD     R2,SP,#4*14                      ; calling SP value
;        STR     R2,[R3]                          ; in case of unexpected exit
;        ; R1 = sprite

;        ; set up the fetchroutine, for use by any subsequent compiled code.
;        ADR     R2,jpeg_fetchroutine
;        STR     R2,fetchroutine

;        ; set up the band buffer pointer and size in the jpeg workspace:
;        ; see h.jpegdata for details of the workspace layout,
;        MOV     R4,R1                            ; keep sprite pointer - R0-R3 trashed by calling C code
;        BL      jpeg_workspace_size              ; call C: R0 = size needed in bytes
;        MOV     R12,SL                           ; R12 is ip to a C prog, will have been trampled on - restore it.
;        ADRL    R1,jpeg_space                    ; base of workspace - a decompress_info_struct
;        ADD     R0,R0,R1                         ; R0 = spare space - the band buffer
;        ADRL    R2,jpeg_band_buffer
;        STR     R0,[R2]                          ; store band buffer pointer
;        ADRL    R2,jpeg_end
;        SUB     R0,R2,R0                         ; band buffer size in bytes
;        MOV     R0,R0,LSR #2                     ; size in words
;        BIC     R0,R0,#15                        ; round down to multiple of 16
;        ADRL    R2,jpeg_band_buffer_size
;        STR     R0,[R2]                          ; store band buffer size
;        MOV     R1,R4                            ; keep hold of sprite pointer

;        STR      R1,save_sprite
;        Pull    "R0-R12,PC"

; ----------------------------------------------------------------------
jpeg_fetchroutine
; This is called every line by compiled code from PutSpriteScaled, when the
; source is JPEG compressed data.
; Entry:
;   r0 = y coordinate
;   r12 = wp
; Exit:
;   r0 = initial address to get RGB data from for this line, based on wp->in_x and given y coord.
;   all other registers preserved.
; This works by calling the C proc jpeg_find_line, defined in h.rojpeg, as:
;   static int *jpeg_find_line(decompress_info_ptr cinfo, int ycoord);

        Push    "R1-R3,R10-R12,LR"               ; r4-r9 are preserved by C code.

        MOV     R1,R0                            ; arg2 - int y coord
        ADRL    R0,jpeg_space                    ; arg1 - decompress_info_ptr cinfo

        ; get ready to call C code
        MOV     SL,R12                           ; will be left alone by compiled C - for debug routines above.

        ; and call
        BL      jpeg_find_line                   ; base of that line in R0 on return
        MOV     R12,SL                           ; R12 is ip to a C prog, will have been trampled on - restore it.

        ; returned value is int* for base of line.
        ; now add in the initial source X coordinate.
        LDR     R1,in_x                          ; x offset, as word count
        ;Debug   cc,"x offset to add",R1
        ADD     R0,R0,R1,LSL #2                  ; add word offset

        Pull    "R1-R3,R10-R12,PC"               ; restore registers and return to compiled code.

      ]

        END