; 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.CFSI-JPEG ; This makes an image of assembler code that can be loaded in by ChangeFSI ; and then called, to decode a JPEG file. ; ; At the start of the image are defined entrypoints. ; Conditions for entering these are: ; lr = return address ; sp -> a useable stack ; r0..r3 = arguments (could be more on stack) ; On exit: ; r0 will contain a returned result, if defined ; r1..r3, lr will be trashed ; all other registers will be preserved ; ; We cope with the whole 26/32-bit thing thus: ; All our C code is APCS-32. The routines like newline() and assert() called ; from our C thus are 32-bit. We don't know about the person using the generated ; CFSI-JPEG file, so we do a run-time check for whether to do a ^ or not on ; return, depending on current mode, in the outer wrapper. GET Hdr:ListOpts GET Hdr:Macros GET Hdr:System GET Hdr:ColourTran GET Hdr:Sprite IMPORT do_jpeg_scan_file IMPORT do_jpeg_scan_file_16 IMPORT jpeg_find_line IMPORT find_image_dims IMPORT assembler_panic EXPORT exit EXPORT dividebyzero AREA |!!!ChangeFSISupport$$Code|, CODE, READONLY, PIC B cfsi_jpeg_scan_file B cfsi_jpeg_find_line B cfsi_find_image_dims B cfsi_jpeg_scan_file_16 DCD 3 ; version number cfsi_jpeg_scan_file ; Entry conditions: r0 -> space (word-aligned) ; r1 = size of space (bytes) ; r2 -> file image in store ; r3 = file image length ; All registers preserved except r0. r0=error code, 0 for OK or other for some error. ; On exit the workspace has some interesting fields at the front: ; struct decompress_info_struct { ; int error_code; /* Returned err code, 0 if no error */ ; int error_argument1; /* Supplementary error data */ ; int error_argument2; /* Supplementary error data */ ; int a; /* don't touch this */ ; int b; /* don't touch this */ ; int /*long*/ image_width; /* overall image width */ ; int /*long*/ image_height; /* overall image height */ ; COLOR_SPACE jpeg_color_space; /* colorspace of JPEG file (1 for greyscale, 3 for YUV) */ ; ... never mind about the rest ; If all is well on exit then error_code will be 0. ; Otherwise it (and r0) is one of: ; #define E_PRE_NOT_8 1 /* Data precision not 8 */ ; #define E_RESTART 2 /* Restart interval not 0 */ ; #define E_MULTI_SCAN 3 /* Multi-scan file */ ; #define E_TOO_HIGH 4 /* Image too high, max is %i pixels */ ; #define E_BAD_SAMPLE 5 /* Bad sample factor */ ; #define E_COLOUR 8 /* Bad colour space (%i), not grey or YUV */ ; #define E_COMPONENTS 9 /* Bad number (%i) of components, only 1 or 3 allowed */ ; #define E_TOO_WIDE 10 /* Image too wide, max is %i pixels */ STMDB sp!,{r1-r12,lr} MOV sl,sp ; used to remember panic exit point BL do_jpeg_scan_file TEQ pc,pc TEQ pc,pc LDMNEIA sp!,{r1-r12,pc}^ ; 26-bit: safe LDMIA sp!,{r1-r12,pc} cfsi_jpeg_scan_file_16 ; Simply call this instead of cfsi_jpeg_scan_file, and subsequent calls to ; cfsi_jpeg_find_line will generate pointers to lines of 16bpp pixels, instead ; of 32bpp ones. ; Entry conditions: r0 -> space (word-aligned) ; r1 = size of space (bytes) ; r2 -> file image in store ; r3 = file image length STMDB sp!,{r1-r12,lr} MOV sl,sp ; used to remember panic exit point BL do_jpeg_scan_file_16 TEQ pc,pc TEQ pc,pc LDMNEIA sp!,{r1-r12,pc}^ ; 26-bit: safe LDMIA sp!,{r1-r12,pc} cfsi_jpeg_find_line ; Entry conditions: r0 -> workspace ; r1 = required y coordinate (in 0..image_size-1) ; On exit r0 will point to the required scan line, one word per pixel, as VIDC20 RGB pixels. STMDB sp!,{r1-r12,lr} MOV sl,sp ; used to remember panic exit point BL jpeg_find_line TEQ pc,pc TEQ pc,pc LDMNEIA sp!,{r1-r12,pc}^ ; 26-bit: safe LDMIA sp!,{r1-r12,pc} cfsi_find_image_dims ; Entry conditions: r0 -> JPEG data ; r1 -> word in which to put image width ; r2 -> word in which to put image height ; r3 -> word in which to put image type - 1=mono, 3=YUV ; r4 -> word in which to put recommended size of workspace for jpeg_scan_file ; On exit, r0=0 if everything is OK, r0!=0 if this data does not look ; like JPEG. STMDB sp!,{r1-r12,lr} MOV sl,sp ; used to remember panic exit point SUB sp,sp,#5*4 MOV r2,sp ; a word for the workspace recommendation ADD r1,sp,#4 ; and 4 words for the result structure BL find_image_dims LDMIA sp!,{r5-r9} ; slurp image_dims_info struct into registers LDMIA sp!,{r1-r4} ; result addresses STR r7,[r1] STR r8,[r2] AND r6,r6,#3 ; just the monochrome/colour bits STR r6,[r3] STR r5,[r4] TEQ pc,pc TEQ pc,pc LDMNEIA sp!,{r5-r12,pc}^ ; 26-bit: safe LDMIA sp!,{r5-r12,pc} exit dividebyzero ; Panic exit from C code. we rely on sl being preserved through ; the c code, and use it to fetch back our call registers. ; On entry here r0 has a panic code. SUBS sp,sl,#0 ; sp := sl, set C for next instruction! TEQ pc,pc ; sets Z if in 32-bit mode LDMNEIA sp!,{r1-r12,pc}^ ; 26-bit: safe LDMIA sp!,{r1-r12,pc} newline assert ; Hope the asserts are OK! MOV pc,lr GBLL cfsi_jpeg cfsi_jpeg SETL {TRUE} GET sources.CSupport GET sources.jdhuff GET sources.jrevdct GET sources.jcconv GET sources.diffuse END