123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- {
- Free Pascal port of the Hermes C library.
- Copyright (C) 2001-2003 Nikolay Nikolov ([email protected])
- Original C version by Christian Nentwich ([email protected])
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- }
- Var
- Processor : Integer;
- Procedure Hermes_Factory_Init;
- Var
- res : Integer;
- Begin
- res := 0;
- Processor := PROC_GENERIC;
- {$IFDEF I386_ASSEMBLER}
- Processor := Processor Or PROC_X86_PENTIUM;{There are no others at the moment}
- res := Hermes_X86_CPU;
- If (res And $800000) <> 0 Then
- Begin
- // Writeln('mmx disabled for debugging');
- Processor := Processor Or PROC_MMX_PENTIUM;
- { Writeln('mmx!');}
- End;
- {$ENDIF I386_ASSEMBLER}
- End;
- Function Hermes_Factory_getClearer(bits : int32) : PHermesClearer;
- Var
- tmp : PHermesClearer;
- Begin
- { Try different processors in order of priority..
- Note that for this to work, an MMX processor has to have both MMX and
- X86 flags }
- tmp := malloc(SizeOf(THermesClearer));
- If tmp = Nil Then
- Begin
- Hermes_Factory_getClearer := Nil;
- Exit;
- End;
- tmp^.bits := bits;
- Hermes_Factory_getClearer := tmp;
- {$IFDEF I386_ASSEMBLER}
- If (Processor And PROC_MMX_PENTIUM) <> 0 Then
- Case bits Of
- 32 : Begin
- tmp^.func := @ClearMMX_32;
- Exit;
- End;
- 24 : ;
- 16 : Begin
- tmp^.func := @ClearMMX_16;
- Exit;
- End;
- 8 : Begin
- tmp^.func := @ClearMMX_8;
- Exit;
- End;
- End;
- If (Processor And PROC_X86_PENTIUM) <> 0 Then
- Case bits Of
- 32 : Begin
- tmp^.func := @ClearX86_32;
- Exit;
- End;
- 24 : ;
- 16 : Begin
- tmp^.func := @ClearX86_16;
- Exit;
- End;
- 8 : Begin
- tmp^.func := @ClearX86_8;
- Exit;
- End;
- End;
- {$ENDIF I386_ASSEMBLER}
- Case bits Of
- 32 : Begin
- tmp^.func := @ClearP_32;
- Exit;
- End;
- 24 : Begin
- tmp^.func := @ClearP_24;
- Exit;
- End;
- 16 : Begin
- tmp^.func := @ClearP_16;
- Exit;
- End;
- 8 : Begin
- tmp^.func := @ClearP_8;
- Exit;
- End;
- Else
- Begin
- free(tmp);
- Hermes_Factory_getClearer := Nil;
- End;
- End;
- End;
- Function Hermes_Factory_getConverter(source, dest : PHermesFormat) : PHermesConverter;
- Var
- tmp : PHermesConverter;
- i : Integer;
- found : Boolean;
- Begin
- found := False;
- tmp := malloc(SizeOf(THermesConverter));
- If tmp = Nil Then
- Begin
- Hermes_Factory_getConverter := Nil;
- Exit;
- End;
- { Set all conversion routines to nil }
- tmp^.loopnormal := Nil;
- tmp^.loopstretch := Nil;
- tmp^.normal := Nil;
- tmp^.stretch := Nil;
- tmp^.dither := Nil;
- tmp^.ditherstretch := Nil;
- tmp^.flags := 0;
- If source^.indexed Then
- { For 8 bit indexed, just look at the destination bit depth and check
- if the converter's processor is a subset of our processor }
- For i := 0 To Factory_NumConverters - 1 Do
- If (Factory_Converters[i].d_bits = dest^.bits) And
- (Factory_Converters[i].s_idx And
- ((processor And Factory_Converters[i].processor) <> 0)) Then
- Begin
- { If any routines are unassigned, assign them now }
- If tmp^.loopnormal = Nil Then
- Begin
- tmp^.loopnormal := Factory_Converters[i].loopnormal;
- found := True;
- End;
- If tmp^.normal = Nil Then
- Begin
- tmp^.normal := Factory_Converters[i].normal;
- found := True;
- End;
- If tmp^.loopstretch = Nil Then
- Begin
- tmp^.loopstretch := Factory_Converters[i].loopstretch;
- found := True;
- End;
- If tmp^.stretch = Nil Then
- Begin
- tmp^.stretch := Factory_Converters[i].stretch;
- found := True;
- End;
- End Else
- Else
- { Otherwise we need to compare everything, including bitmasks }
- For i := 0 To Factory_NumConverters - 1 Do
- If (Factory_Converters[i].d_bits = dest^.bits) And
- (Factory_Converters[i].d_r = dest^.r) And
- (Factory_Converters[i].d_g = dest^.g) And
- (Factory_Converters[i].d_b = dest^.b) And
- (Factory_Converters[i].d_a = dest^.a) And
- (Factory_Converters[i].d_idx = dest^.indexed) And
- (Factory_Converters[i].s_bits = source^.bits) And
- (Factory_Converters[i].s_r = source^.r) And
- (Factory_Converters[i].s_g = source^.g) And
- (Factory_Converters[i].s_b = source^.b) And
- (Factory_Converters[i].s_a = source^.a) And
- (Factory_Converters[i].s_idx = source^.indexed) And
- ((processor And Factory_Converters[i].processor) <> 0) Then
- Begin
- { If any routines are unassigned, assign them now }
- If (tmp^.loopnormal = Nil) And
- (Factory_Converters[i].loopnormal <> Nil) Then
- Begin
- tmp^.loopnormal := Factory_Converters[i].loopnormal;
- found := True;
- End;
- If (tmp^.normal = Nil) And
- (Factory_Converters[i].normal <> Nil) Then
- Begin
- tmp^.normal := Factory_Converters[i].normal;
- found := True;
- End;
- If (tmp^.loopstretch = Nil) And
- (Factory_Converters[i].loopstretch <> Nil) Then
- Begin
- tmp^.loopstretch := Factory_Converters[i].loopstretch;
- found := True;
- End;
- If (tmp^.stretch = Nil) And
- (Factory_Converters[i].stretch <> Nil) Then
- Begin
- tmp^.stretch := Factory_Converters[i].stretch;
- found := True;
- End;
- If (tmp^.dither = Nil) And
- (Factory_Converters[i].dither <> Nil) Then
- Begin
- tmp^.dither := Factory_Converters[i].dither;
- found := True;
- End;
- If (tmp^.ditherstretch = Nil) And
- (Factory_Converters[i].ditherstretch <> Nil) Then
- Begin
- tmp^.ditherstretch := Factory_Converters[i].ditherstretch;
- found := True;
- End;
- { In the rare event of having everything assigned, pull the emergency
- break. Otherwise we need to continue looking (might be stretching
- routines somewhere :)
- Do I sound like a stewardess? }
- If (tmp^.loopnormal <> Nil) And (tmp^.normal <> Nil) And
- (tmp^.loopstretch <> Nil) And (tmp^.stretch <> Nil) And
- (tmp^.dither <> Nil) And (tmp^.ditherstretch <> Nil) Then
- Break;
- End;
- If found Then
- Begin
- Hermes_FormatCopy(source, @tmp^.source);
- Hermes_FormatCopy(dest, @tmp^.dest);
- Hermes_Factory_getConverter := tmp;
- End
- Else
- Begin
- free(tmp);
- Hermes_Factory_getConverter := Nil;
- End;
- End;
- Function Hermes_Factory_getEqualConverter(bits : Integer) : PHermesConverter;
- Var
- found : Boolean;
- tmp : PHermesConverter;
- asm_found : Integer;
- c_found : Integer;
- Begin
- found := False;
- tmp := malloc(SizeOf(THermesConverter));
- If tmp = Nil Then
- Begin
- Hermes_Factory_getEqualConverter := Nil;
- Exit;
- End;
- { Set all conversion routines to null }
- tmp^.loopnormal := Nil;
- tmp^.loopstretch := Nil;
- tmp^.normal := Nil;
- tmp^.stretch := Nil;
- tmp^.dither := Nil;
- tmp^.ditherstretch := Nil;
- {$IFDEF I386_ASSEMBLER}
- { Try MMX routines }
- If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
- (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
- If (processor And PROC_MMX_PENTIUM) <> 0 Then
- { Case bits Of
- End};
- { Try X86 routines }
- If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
- (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
- If (processor And PROC_X86_PENTIUM) <> 0 Then
- Begin
- asm_found := 0;
- Case bits Of
- 32 : Begin
- tmp^.normal := @CopyX86p_4byte; asm_found := 1;
- End;
- 24 : ;
- 16 : Begin
- tmp^.normal := @CopyX86p_2byte; asm_found := 1;
- End;
- 8 : Begin
- tmp^.normal := @CopyX86p_1byte; asm_found := 1;
- End;
- End;
- If (asm_found And 1) <> 0 Then
- Begin
- tmp^.loopnormal := @ConvertX86;
- found := True;
- End;
- End;
- {$ENDIF I386_ASSEMBLER}
- If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
- (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
- Begin
- c_found := 0;
- Case bits Of
- 32 : Begin
- If tmp^.normal = Nil Then
- Begin
- tmp^.normal := @CopyP_4byte; c_found := c_found Or 1;
- End;
- If tmp^.stretch = Nil Then
- Begin
- tmp^.stretch := @CopyP_4byte_S; c_found := c_found Or 2;
- End;
- End;
- 24 : Begin
- If tmp^.normal = Nil Then
- Begin
- tmp^.normal := @CopyP_3byte; c_found := c_found Or 1;
- End;
- If tmp^.stretch = Nil Then
- Begin
- tmp^.stretch := @CopyP_3byte_S; c_found := c_found Or 2;
- End;
- End;
- 16 : Begin
- If tmp^.normal = Nil Then
- Begin
- tmp^.normal := @CopyP_2byte; c_found := c_found Or 1;
- End;
- If tmp^.stretch = Nil Then
- Begin
- tmp^.stretch := @CopyP_2byte_S; c_found := c_found Or 2;
- End;
- End;
- 8 : Begin
- If tmp^.normal = Nil Then
- Begin
- tmp^.normal := @CopyP_1byte; c_found := c_found Or 1;
- End;
- If tmp^.stretch = Nil Then
- Begin
- tmp^.stretch := @CopyP_1byte_S; c_found := c_found Or 2;
- End;
- End;
- End;
- If (c_found And 1) <> 0 Then
- Begin
- tmp^.loopnormal := @ConvertP; found := True;
- End;
- If (c_found And 2) <> 0 Then
- Begin
- tmp^.loopstretch := @ConvertPStretch; found := True;
- End;
- End;
- If found Then
- Hermes_Factory_getEqualConverter := tmp
- Else
- Begin
- free(tmp);
- Hermes_Factory_getEqualConverter := Nil;
- End;
- End;
|